BLE Keyboard(Surface キーボード) の Report Map
BLEのHIDキーボードのReport Map をキャプチャしたので載せる。
自分でBLE キーボードを作る際にどういうReport Mapにしたら良いのか参考にする。
HOGPの規格書を読んで理解してゼロから作るのが正しい方法なのだろうが、結構大変なので、既存のキーボードのデータをパクることにする。
なお、世の中にBLEキーボードが全然発売されてない!!
Bluetoothキーボードは多々あるが、これはHIDキーボードであって、HOGPに対応しているわけではない。要はBluetooth Classic対応のキーボードはあまたあるが、自分が調べた限りBLE HID Keyboardは、MicrosoftのSurfaceキーボードしかなかった。
(正確には過去に同じくMicrosoftから発売されていたUniversal Foldable Keyboardが存在していたが、今は売ってない)
なぜこんなにBLEキーボードがないのかは知らん。互換性かなんかだろうか?
Surface Keyboard の Report Map
Report Map: 05010906a10185011500250105071ae0002ae700750195088102050719002a910016000026ff007508950a8100050c0ac002a1021ac1022ac6029506b103c0050875019503190129032501910295059101c0050c0901a101851019002aff03750c9501150026ff038100750495018101c00607ff0982a101150026ff0075089513852709c6820201852209c8b20201852409cbb202019510852809cc82020109d092020109d4b20201c00607ff0980a1018530150025ff9501750809009102c00981a101852a150025ff7508954809c682020109c7920201953c09c8b20201852b09c982020109ca92020109cbb20201852c7520950419cc29cf810219d029d3910219d429d7b102852d19d829db810219dc29df910219e029e3b102852e19e429e7810219e829eb910219ec29efb102852f19f029f3810219f429f7910219f829fbb102c005010980a10185021500250109970998099975019503810295058101c0
長い。
こんなの規格書見ながら頑張ってパースするなんてありえないので、そういうことができるツールにかける。
USB Descriptor and Request Parser(https://eleccelerator.com/usbdescreqparser/)
と、
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x06, // Usage (Keyboard)
0xA1, 0x01, // Collection (Application)
0x85, 0x01, // Report ID (1)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x05, 0x07, // Usage Page (Kbrd/Keypad)
0x1A, 0xE0, 0x00, // Usage Minimum (0xE0)
0x2A, 0xE7, 0x00, // Usage Maximum (0xE7)
0x75, 0x01, // Report Size (1)
0x95, 0x08, // Report Count (8)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x07, // Usage Page (Kbrd/Keypad)
0x19, 0x00, // Usage Minimum (0x00)
0x2A, 0x91, 0x00, // Usage Maximum (0x91)
0x16, 0x00, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x00, // Logical Maximum (255)
0x75, 0x08, // Report Size (8)
0x95, 0x0A, // Report Count (10)
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x0C, // Usage Page (Consumer)
0x0A, 0xC0, 0x02, // Usage (0x02C0)
0xA1, 0x02, // Collection (Logical)
0x1A, 0xC1, 0x02, // Usage Minimum (0x02C1)
0x2A, 0xC6, 0x02, // Usage Maximum (0x02C6)
0x95, 0x06, // Report Count (6)
0xB1, 0x03, // Feature (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection
0x05, 0x08, // Usage Page (LEDs)
0x75, 0x01, // Report Size (1)
0x95, 0x03, // Report Count (3)
0x19, 0x01, // Usage Minimum (Num Lock)
0x29, 0x03, // Usage Maximum (Scroll Lock)
0x25, 0x01, // Logical Maximum (1)
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x95, 0x05, // Report Count (5)
0x91, 0x01, // Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection
0x05, 0x0C, // Usage Page (Consumer)
0x09, 0x01, // Usage (Consumer Control)
0xA1, 0x01, // Collection (Application)
0x85, 0x10, // Report ID (16)
0x19, 0x00, // Usage Minimum (Unassigned)
0x2A, 0xFF, 0x03, // Usage Maximum (0x03FF)
0x75, 0x0C, // Report Size (12)
0x95, 0x01, // Report Count (1)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x03, // Logical Maximum (1023)
0x81, 0x00, // Input (Data,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x75, 0x04, // Report Size (4)
0x95, 0x01, // Report Count (1)
0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0, // End Collection
0x06, 0x07, 0xFF, // Usage Page (Vendor Defined 0xFF07)
0x09, 0x82, // Usage (0x82)
0xA1, 0x01, // Collection (Application)
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x00, // Logical Maximum (255)
0x75, 0x08, // Report Size (8)
0x95, 0x13, // Report Count (19)
0x85, 0x27, // Report ID (39)
0x09, 0xC6, // Usage (0xC6)
0x82, 0x02, 0x01, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Buffered Bytes)
0x85, 0x22, // Report ID (34)
0x09, 0xC8, // Usage (0xC8)
0xB2, 0x02, 0x01, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile,Buffered Bytes)
0x85, 0x24, // Report ID (36)
0x09, 0xCB, // Usage (0xCB)
0xB2, 0x02, 0x01, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile,Buffered Bytes)
0x95, 0x10, // Report Count (16)
0x85, 0x28, // Report ID (40)
0x09, 0xCC, // Usage (0xCC)
0x82, 0x02, 0x01, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Buffered Bytes)
0x09, 0xD0, // Usage (0xD0)
0x92, 0x02, 0x01, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile,Buffered Bytes)
0x09, 0xD4, // Usage (0xD4)
0xB2, 0x02, 0x01, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile,Buffered Bytes)
0xC0, // End Collection
0x06, 0x07, 0xFF, // Usage Page (Vendor Defined 0xFF07)
0x09, 0x80, // Usage (0x80)
0xA1, 0x01, // Collection (Application)
0x85, 0x30, // Report ID (48)
0x15, 0x00, // Logical Minimum (0)
0x25, 0xFF, // Logical Maximum (-1)
0x95, 0x01, // Report Count (1)
0x75, 0x08, // Report Size (8)
0x09, 0x00, // Usage (0x00)
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection
0x09, 0x81, // Usage (0x81)
0xA1, 0x01, // Collection (Application)
0x85, 0x2A, // Report ID (42)
0x15, 0x00, // Logical Minimum (0)
0x25, 0xFF, // Logical Maximum (-1)
0x75, 0x08, // Report Size (8)
0x95, 0x48, // Report Count (72)
0x09, 0xC6, // Usage (0xC6)
0x82, 0x02, 0x01, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Buffered Bytes)
0x09, 0xC7, // Usage (0xC7)
0x92, 0x02, 0x01, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile,Buffered Bytes)
0x95, 0x3C, // Report Count (60)
0x09, 0xC8, // Usage (0xC8)
0xB2, 0x02, 0x01, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile,Buffered Bytes)
0x85, 0x2B, // Report ID (43)
0x09, 0xC9, // Usage (0xC9)
0x82, 0x02, 0x01, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Buffered Bytes)
0x09, 0xCA, // Usage (0xCA)
0x92, 0x02, 0x01, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile,Buffered Bytes)
0x09, 0xCB, // Usage (0xCB)
0xB2, 0x02, 0x01, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile,Buffered Bytes)
0x85, 0x2C, // Report ID (44)
0x75, 0x20, // Report Size (32)
0x95, 0x04, // Report Count (4)
0x19, 0xCC, // Usage Minimum (0xCC)
0x29, 0xCF, // Usage Maximum (0xCF)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x19, 0xD0, // Usage Minimum (0xD0)
0x29, 0xD3, // Usage Maximum (0xD3)
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x19, 0xD4, // Usage Minimum (0xD4)
0x29, 0xD7, // Usage Maximum (0xD7)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x2D, // Report ID (45)
0x19, 0xD8, // Usage Minimum (0xD8)
0x29, 0xDB, // Usage Maximum (0xDB)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x19, 0xDC, // Usage Minimum (0xDC)
0x29, 0xDF, // Usage Maximum (0xDF)
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x19, 0xE0, // Usage Minimum (0xE0)
0x29, 0xE3, // Usage Maximum (0xE3)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x2E, // Report ID (46)
0x19, 0xE4, // Usage Minimum (0xE4)
0x29, 0xE7, // Usage Maximum (0xE7)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x19, 0xE8, // Usage Minimum (0xE8)
0x29, 0xEB, // Usage Maximum (0xEB)
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x19, 0xEC, // Usage Minimum (0xEC)
0x29, 0xEF, // Usage Maximum (0xEF)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x2F, // Report ID (47)
0x19, 0xF0, // Usage Minimum (0xF0)
0x29, 0xF3, // Usage Maximum (0xF3)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x19, 0xF4, // Usage Minimum (0xF4)
0x29, 0xF7, // Usage Maximum (0xF7)
0x91, 0x02, // Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x19, 0xF8, // Usage Minimum (0xF8)
0x29, 0xFB, // Usage Maximum (0xFB)
0xB1, 0x02, // Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0, // End Collection
0x05, 0x01, // Usage Page (Generic Desktop Ctrls)
0x09, 0x80, // Usage (Sys Control)
0xA1, 0x01, // Collection (Application)
0x85, 0x02, // Report ID (2)
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
0x09, 0x97, // Usage (0x97)
0x09, 0x98, // Usage (0x98)
0x09, 0x99, // Usage (0x99)
0x75, 0x01, // Report Size (1)
0x95, 0x03, // Report Count (3)
0x81, 0x02, // Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x05, // Report Count (5)
0x81, 0x01, // Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0, // End Collection
// 354 bytes
Report Count : レポートの数
Report Size : レポート1つあたりのサイズ(bit)
例えば、
Report Count : 3
Report Size : 4
だった場合、3個の4bitレポートがあるので、サイズは12bitになる。
以上。