蓝牙HID LINUX下描述符解析

    本文地址:http://tongxinmao.com/Article/Detail/id/419

    文章内容提示

    这篇文章主要说明如何获取与查看USB和BLE HoGP HID设备报告描述符,如何根据获取的描述符读懂report。然后说明了可以使用hidrd-convert工具,来如何根据hex报告描述符转化得到C语言格式的描述符,这对于我们编码是有意义的。 其中,还截取了USB 逻辑分析仪,Wireshark等工具来查看input report。




    如何看懂HID report descriptor

    对于如何看懂HID报告描述符,几乎离不开下面的这两个pdf:


    USB HID Usage Table


    USB HID Spec


    先看文档(USB HID设备)弄明白一些基本概念:



    项目Item的意义

    collection与end collection:namespace的意义,相当于将多个usage page

    usage page与 usage

    Logical Minimum 与 Logical Maximum 

    Usage Minimum 与 Usage Maximum

    input

    report size 与 report count


    个人认为先准备好这份文档,然后结合一些文章来理解比较快速。以下是个人认为的快速理解的步骤:


    1. 看这篇(Tutorial about USB HID Report Descriptors)文章,理解一些基本的概念,主要弄明白概念4与5


    2. 不要太过于纠结如何从hex转换到方便大家阅读的格式的report


    例如下面这个描述符,我们应该直接看注释而,然后可以知道描述的是mouse,然后根据usage page和usage的值在usage table pdf中找到对应的描述,然后根据对基本概念的了解知道如果鼠标的一个按键按下那么会生成怎么样的report即可:



        0x05, 0x01,  // Usage Page (Generic Desktop)

        0x09, 0x02,  // Usage (Mouse)

        0xA1, 0x01,  // Collection (Application)

        0x85, 0x01,  // Report Id (1)

        0x09, 0x01,  //   Usage (Pointer)

        0xA1, 0x00,  //   Collection (Physical)

        0x05, 0x09,  //     Usage Page (Buttons)

        0x19, 0x01,  //     Usage Minimum (01) - Button 1

        0x29, 0x03,  //     Usage Maximum (03) - Button 3

        0x15, 0x00,  //     Logical Minimum (0)

        0x25, 0x01,  //     Logical Maximum (1)

        0x75, 0x01,  //     Report Size (1)

        0x95, 0x03,  //     Report Count (3)

        0x81, 0x02,  //     Input (Data, Variable, Absolute) - Button states

        0x75, 0x05,  //     Report Size (5)

        0x95, 0x01,  //     Report Count (1)

        0x81, 0x01,  //     Input (Constant) - Padding or Reserved bits

        0x05, 0x01,  //     Usage Page (Generic Desktop)

        0x09, 0x30,  //     Usage (X)

        0x09, 0x31,  //     Usage (Y)

        0x09, 0x38,  //     Usage (Wheel)

        0x15, 0x81,  //     Logical Minimum (-127)

        0x25, 0x7F,  //     Logical Maximum (127)

        0x75, 0x08,  //     Report Size (8)

        0x95, 0x03,  //     Report Count (3)

        0x81, 0x06,  //     Input (Data, Variable, Relative) - X & Y coordinate

        0xC0,        //   End Collection

        0xC0,        // End Collection


    3. 看后面的 “1. 使用usbhid-dump工具获取报告描述符” 章节了解report字节数的构成来源

    需要注意的是input是报告给主机(例如PC,Android)的,因此只能算input的,在主机到设备的时候只能算output的


    4. 看文章《HID reports》,结合pdf弄明白一个keyboard的report为何是8个字节,在USB interrupt IN中传输的数据是怎么样的。也可以看后面的USB分析仪给出的例子。


    5. 了解hex如何对应不同的Tag,看这篇文章






    BT中的HoGP, USB HID设备


    如何看懂HID reports


    蓝牙BLE的HoGP生成的report




    Linux下如何查看report

    这里需要区分USB HID与BT通过HoGP生成的HID设备,这两种方式生成的HID设备描述符可以使用的工具不一样。


    USB HID设备

    1. 使用usbhid-dump工具获取报告描述符

    在Linux下,如果一个USB HID设备插入后,在dmesg中可以看到具体的信息,然后可以看到其生成的hid input设备号,例如下面这个设备生成了多个hid input设备



    [290714.058419] usb 3-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3

    [290714.058420] usb 3-4: Product: BLE Remote KMA Dongle

    [290714.058421] usb 3-4: Manufacturer: Telink

    [290714.058422] usb 3-4: SerialNumber: TLSR826X

    [290714.058535] usb 3-4: ep 0x81 - rounding interval to 64 microframes, ep desc says 80 microframes

    [290714.060464] usblp 3-4:1.0: usblp0: USB Bidirectional printer dev 29 if 0 alt 0 proto 2 vid 0x248A pid 0x981D

    [290714.092288] input: Telink BLE Remote KMA Dongle as /devices/pci0000:00/0000:00:14.0/usb3/3-4/3-4:1.3/0003:248A:981D.000B/input/input22

    [290714.145485] hid-generic 0003:248A:981D.000B: input,hidraw2: USB HID v1.11 Keyboard [Telink BLE Remote KMA Dongle] on usb-0000:00:14.0-4/input3

    [290714.155837] input: Telink BLE Remote KMA Dongle as /devices/pci0000:00/0000:00:14.0/usb3/3-4/3-4:1.4/0003:248A:981D.000C/input/input23

    [290714.209579] hid-generic 0003:248A:981D.000C: input,hidraw3: USB HID v1.11 Mouse [Telink BLE Remote KMA Dongle] on usb-0000:00:14.0-4/input4


    上面生成了三个HID Input设备,我们选中其中一个用来分析HID report descriptor。选取的一个设备的描述符为:



    $ sudo usbhid-dump  -d 248a -i 255 | grep -v : | xxd -r -p | hidrd-convert -o spec

    Usage Page (Desktop),                   ; Generic desktop controls (01h)

    Usage (Mouse),                          ; Mouse (02h, application collection)

    Collection (Application),

        Report ID (1),

        Usage (Pointer),                    ; Pointer (01h, physical collection)

        Collection (Physical),

            Usage Page (Button),            ; Button (09h)

            Usage Minimum (01h),

            Usage Maximum (05h),

            Logical Minimum (0),

            Logical Maximum (1),

            Report Count (5),

            Report Size (1),

            Input (Variable),

            Report Count (1),

            Report Size (3),

            Input (Constant),

            Usage Page (Desktop),           ; Generic desktop controls (01h)

            Usage (X),                      ; X (30h, dynamic value)

            Usage (Y),                      ; Y (31h, dynamic value)

            Logical Minimum (-127),

            Logical Maximum (127),

            Report Size (8),

            Report Count (2),

            Input (Variable, Relative),

            Usage (Wheel),                  ; Wheel (38h, dynamic value)

            Logical Minimum (-127),

            Logical Maximum (127),

            Report Size (8),

            Report Count (1),

            Input (Variable, Relative),

        End Collection,

    End Collection,

    Usage Page (Consumer),                  ; Consumer (0Ch)

    Usage (Consumer Control),               ; Consumer control (01h, application collection)

    Collection (Application),

        Report ID (3),

        Report Size (16),

        Report Count (2),

        Logical Minimum (1),

        Logical Maximum (668),

        Usage Minimum (Consumer Control),   ; Consumer control (01h, application collection)

        Usage Maximum (AC Send),            ; AC send (028Ch, selector)

        Input,

    End Collection,

    Usage Page (Desktop),                   ; Generic desktop controls (01h)

    Usage (Sys Control),                    ; System control (80h, application collection)

    Collection (Application),

        Report ID (4),

        Report Size (2),

        Report Count (1),

        Logical Minimum (1),

        Logical Maximum (3),

        Usage (Sys Sleep),                  ; System sleep (82h, one-shot control)

        Usage (Sys Power Down),             ; System power down (81h, one-shot control)

        Usage (Sys Wake Up),                ; System wake up (83h, one-shot control)

        Input (No Preferred, Null State),

        Report Size (6),

        Input (Constant, Variable),

    End Collection,

    Usage Page (Desktop),                   ; Generic desktop controls (01h)

    Usage (00h),

    Collection (Application),

        Report ID (5),

        Usage Page (FF00h),                 ; FF00h, vendor-defined

        Usage (01h),

        Logical Minimum (-127),

        Logical Maximum (127),

        Report Size (8),

        Report Count (7),

        Feature (Variable),

    End Collection,

    Usage Page (Desktop),                   ; Generic desktop controls (01h)

    Usage (Keyboard),                       ; Keyboard (06h, application collection)

    Collection (Application),

        Usage Page (Keyboard),              ; Keyboard/keypad (07h)

        Usage Minimum (KB Leftcontrol),     ; Keyboard left control (E0h, dynamic value)

        Usage Maximum (KB Right GUI),       ; Keyboard right GUI (E7h, dynamic value)

        Logical Minimum (0),

        Logical Maximum (1),

        Report Count (8),

        Report Size (1),

        Input (Variable),

        Input (Constant, Variable),

        Report Count (5),

        Usage Page (LED),                   ; LEDs (08h)

        Usage Minimum (01h),

        Usage Maximum (05h),

        Output (Variable),

        Report Count (1),

        Report Size (3),

        Output (Constant),

        Report Count (6),

        Report Size (8),

        Logical Minimum (0),

        Logical Maximum (164),

        Usage Page (Keyboard),              ; Keyboard/keypad (07h)

        Usage Minimum (None),               ; No event (00h, selector)

        Usage Maximum (KB ExSel),           ; Keyboard ExSel (A4h, selector)

        Input,

    End Collection

    后面我们将使用这个设备的报告描述符中的reportID=3的item为例,对其report进行监听和分析。下面是对这个reportID对应的collect的摘抄:


    Usage Page (Consumer),                  ; Consumer (0Ch)

    Usage (Consumer Control),               ; Consumer control (01h, application collection)

    Collection (Application),

        Report ID (3),

        Report Size (16),

        Report Count (2),

        Logical Minimum (1),

        Logical Maximum (668),

        Usage Minimum (Consumer Control),   ; Consumer control (01h, application collection)

        Usage Maximum (AC Send),            ; AC send (028Ch, selector)

        Input,

    End Collection,


    可以看到其report size=16, 即16bits,也就是2Bytes,即每个Filed使用2B来表示,而report count=2, 即有两个filed,故每次的输入报告的字节数(这里面只算input,这个例子也只有input)总共为4个Byte。这里面还有一个report ID =3, 因此我们可以知道每次发送report的时候,将会有5个字节,格式为:

    reportID + 4B的reportValue


    这个在后面的图Wireshark中由体现和说明,也在后面的USB 逻辑分析仪图中由表示,同时在usbhid-dump的示例中也有log,具体可以结合此来分析。


    使用调试接口查看BLE HoGP与USB HID的描述符

    见文章后面的内容。


    监听获取的report

    使用usbhid-dump

    按下Volume Down:



    $ sudo usbhid-dump -es -m  248a:981d

    Starting dumping interrupt transfer stream

    with 1 minute timeout.


    003:029:004:STREAM             1507801668.759133

     03 EA 00 00 00


    003:029:004:STREAM             1507801668.907180

     03 00 00 00 00



    使用hid的调试接口获取报告描述符

    不管是对于USB HID还是BLE过来的通过HoGP生成的HID设备,在/sys/kernel/debug/hid下面都有暴露对应的调试接口,从这边我们可以结合hidrd工具来获取他们的HID报告描述符。


    这种方式尤其对于BLE HoGP设备非常有用,如果我们身边没有蓝牙转包工具的时候。


    首先切换到root用户,然后进入到debug接口目录中:



    root@hexiongjun-9020:~# cd /sys/kernel/debug/hid/

    root@hexiongjun-9020:/sys/kernel/debug/hid# ls

    0003:04CA:0061.0001  0003:248A:981D.0013  0003:248A:981D.0014  0003:413C:2107.0002


    在这些设备里面有rdesc和event两个文件,这两个文件的前者是report descriptor,dump一个出来作为例子:



    root@hexiongjun-9020:/sys/kernel/debug/hid# cat 0003*/rdesc

    05 01 09 02 a1 01 09 01 a1 00 05 09 19 01 29 03 15 00 25 01 95 08 75 01 81 02 05 01 09 30 09 31 09 38 15 81 25 7f 75 08 95 03 81 06 c0 c0 



      INPUT[INPUT]

        Field(0)

          Physical(GenericDesktop.Pointer)

          Application(GenericDesktop.Mouse)

          Usage(8)

            Button.0001

            Button.0002

            Button.0003

            Button.0003

            Button.0003

            Button.0003

            Button.0003

            Button.0003

          Logical Minimum(0)

          Logical Maximum(1)

          Report Size(1)

          Report Count(8)

          Report Offset(0)

          Flags( Variable Absolute )

        Field(1)

          Physical(GenericDesktop.Pointer)

          Application(GenericDesktop.Mouse)

          Usage(3)

            GenericDesktop.X

            GenericDesktop.Y

            GenericDesktop.Wheel

          Logical Minimum(-127)

          Logical Maximum(127)

          Report Size(8)

          Report Count(3)

          Report Offset(8)

          Flags( Variable Relative )



    Button.0001 ---> Key.LeftBtn

    Button.0002 ---> Key.RightBtn

    Button.0003 ---> Key.MiddleBtn

    Button.0003 ---> Key.SideBtn

    Button.0003 ---> Key.ExtraBtn

    Button.0003 ---> Key.ForwardBtn

    Button.0003 ---> Key.BackBtn

    Button.0003 ---> Key.TaskBtn

    GenericDesktop.X ---> Relative.X

    GenericDesktop.Y ---> Relative.Y

    GenericDesktop.Wheel ---> Relative.Wheel


    第一部分的hex array是hex格式的report descriptor,后面的是解析后的方便人看的风格的report descriptor。



    蓝牙与USB HID设备的report descriptor查看方法

    其中前面的那一串hex数值,是hex格式的描述符,我们可以使用hidrd-convert来转换。在下面我们将用这个为例子说明。



    $ echo '05 01 09 02 a1 01 09 01 a1 00 05 09 19 01 29 03 15 00 25 01 95 08 75 01 81 02 05 01 09 30 09 31 09 38 15 81 25 7f 75 08 95 03 81 06 c0 c0' | xxd -r -p | hidrd-convert -o spec

    Usage Page (Desktop),               ; Generic desktop controls (01h)

    Usage (Mouse),                      ; Mouse (02h, application collection)

    Collection (Application),

        Usage (Pointer),                ; Pointer (01h, physical collection)

        Collection (Physical),

            Usage Page (Button),        ; Button (09h)

            Usage Minimum (01h),

            Usage Maximum (03h),

            Logical Minimum (0),

            Logical Maximum (1),

            Report Count (8),

            Report Size (1),

            Input (Variable),

            Usage Page (Desktop),       ; Generic desktop controls (01h)

            Usage (X),                  ; X (30h, dynamic value)

            Usage (Y),                  ; Y (31h, dynamic value)

            Usage (Wheel),              ; Wheel (38h, dynamic value)

            Logical Minimum (-127),

            Logical Maximum (127),

            Report Size (8),

            Report Count (3),

            Input (Variable, Relative),

        End Collection,

    End Collection



    hidrd-convet的功能不仅仅是将hex array转换成可行性好的spec格式,也可以将其转换成C语言分割,XML格式。


    具体看法常见hidid工具的github主页,或者使用hidrd-convert --help说明。


    另外,hidrd项目已经有许多年没有更新了,基本功能可用,但是可能会出现问题。在Ubuntu 14.04和16.04下面ld-config配置不正确,所以会导致在运行hidrd相关程序的时候出现找不到库。对此我在项目中提交了issue:library is not found when execute the hid-convert in Ubuntu 14.04 and 16.04 after make install #19, 对于这个问题,可以设置LD_LIBRARY_PATH环境变量来解决。


    USB分析仪中的report

    如果使用Beagle USB Analyzer来抓包的话,input report会被分析仪解析出来,结果如下:




    WireShark转包查看report

    Wireshark抓包分析USB需要先安装usbmon模块:



    sudo modprobe usbmon


    然后确定需要分析的USB设备的USB Bus ID:



    $ lsusb | grep 248A:981D -i

    Bus 003 Device 029: ID 248a:981d  


    据此知道其位于USB Bus3上面,因此在打开Wireshark后选择usbmon3,然后就可以抓包了。


    和USB分析仪一样,我们选择同样的Volume Down为例,下面是截图,带有Wireshark的分析的说明:


    Windows下如何查看report






    后面的数据便是report data了。格式为ReportID + Input数值Arrary




    参考

    0. dump hid report in Linux


    1. Tutorial about USB HID Report Descriptors


    2. DigiMend: Collecting tablet diagnostics

    ————————————————

    版权声明:本文为CSDN博主「TonyHo」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。

    原文链接:https://blog.csdn.net/sy373466062/article/details/78223563


    上一篇:蓝牙HID
    下一篇:国外电子网站