仅根据 DESCRIPTOR HID 报告访问 USB 设备数据
Accessing USB device data based only on DESCRIPTOR HID Report
我有一个带 USB 的数字声级计(声压计)GM1356。 Windows 上有一些软件可以处理它,但我没有 CD,也无法在 Internet 上使用。我想要做的是读取它关于 Linux 上当前噪音水平的数据。
我发现已经有一个库允许我使用我知道的语言(ruby、libusb)来执行此操作。在下一步中,我安装了 wireshark 来检查它发送给 pc 的内容。它不会发送太多。我发现的最有趣的数据包是 DESCRIPTOR HID Report
。我想知道接下来我应该采取什么步骤来阅读我感兴趣的数据。我如何确定我应该发送哪些请求来获取它?
HID Report
Global item (Usage)
Header
.... ..10 = bSize: 2 bytes (2)
.... 01.. = bType: Global (1)
0000 .... = bTag: Usage (0x0)
Usage page: [Vendor-defined] (0xffa0)
Local item (Usage)
Header
.... ..01 = bSize: 1 byte (1)
.... 10.. = bType: Local (2)
0000 .... = bTag: Usage (0x0)
Usage: [Vendor-defined] (0xffa00001)
Main item (Collection)
Header
.... ..01 = bSize: 1 byte (1)
.... 00.. = bType: Main (0)
1010 .... = bTag: Collection (0xa)
Collection type: Application (0x01)
Local item (Usage)
Header
.... ..01 = bSize: 1 byte (1)
.... 10.. = bType: Local (2)
0000 .... = bTag: Usage (0x0)
Usage: [Vendor-defined] (0xffa00002)
Main item (Collection)
Header
.... ..01 = bSize: 1 byte (1)
.... 00.. = bType: Main (0)
1010 .... = bTag: Collection (0xa)
Collection type: Physical (0x00)
Global item (Usage)
Header
.... ..10 = bSize: 2 bytes (2)
.... 01.. = bType: Global (1)
0000 .... = bTag: Usage (0x0)
Usage page: [Vendor-defined] (0xffa1)
Local item (Usage)
Header
.... ..01 = bSize: 1 byte (1)
.... 10.. = bType: Local (2)
0000 .... = bTag: Usage (0x0)
Usage: [Vendor-defined] (0xffa10003)
Local item (Usage)
Header
.... ..01 = bSize: 1 byte (1)
.... 10.. = bType: Local (2)
0000 .... = bTag: Usage (0x0)
Usage: [Vendor-defined] (0xffa10004)
Global item (Logical minimum)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
0001 .... = bTag: Logical minimum (0x1)
Logical minimum: 128
Global item (Logical maximum)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
0010 .... = bTag: Logical maximum (0x2)
Logical maximum: 127
Global item (Physical minimum)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
0011 .... = bTag: Physical minimum (0x3)
Physical minimum: 0
Global item (Physical maximum)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
0100 .... = bTag: Physical maximum (0x4)
Physical maximum: 255
Global item (Report size)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
0111 .... = bTag: Report size (0x7)
Report size: 8
Global item (Report count)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
1001 .... = bTag: Report count (0x9)
Report count: 8
Main item (Input)
Header
.... ..01 = bSize: 1 byte (1)
.... 00.. = bType: Main (0)
1000 .... = bTag: Input (0x8)
.... .... 0 = Data/constant: Data
.... ...1 . = Data type: Variable
.... ..0. . = Coordinates: Absolute
.... .0.. . = Min/max wraparound: No Wrap
.... 0... . = Physical relationship to data: Linear
...0 .... . = Preferred state: Preferred State
..0. .... . = Has null position: No Null position
.0.. .... . = [Reserved]: False
0... .... . = Bits or bytes: Buffered bytes (default, no second byte present)
Local item (Usage)
Header
.... ..01 = bSize: 1 byte (1)
.... 10.. = bType: Local (2)
0000 .... = bTag: Usage (0x0)
Usage: [Vendor-defined] (0xffa10005)
Local item (Usage)
Header
.... ..01 = bSize: 1 byte (1)
.... 10.. = bType: Local (2)
0000 .... = bTag: Usage (0x0)
Usage: [Vendor-defined] (0xffa10006)
Global item (Logical minimum)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
0001 .... = bTag: Logical minimum (0x1)
Logical minimum: 128
Global item (Logical maximum)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
0010 .... = bTag: Logical maximum (0x2)
Logical maximum: 127
Global item (Physical minimum)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
0011 .... = bTag: Physical minimum (0x3)
Physical minimum: 0
Global item (Physical maximum)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
0100 .... = bTag: Physical maximum (0x4)
Physical maximum: 255
Global item (Report size)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
0111 .... = bTag: Report size (0x7)
Report size: 8
Global item (Report count)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
1001 .... = bTag: Report count (0x9)
Report count: 8
Main item (Output)
Header
.... ..01 = bSize: 1 byte (1)
.... 00.. = bType: Main (0)
1001 .... = bTag: Output (0x9)
.... .... 0 = Data/constant: Data
.... ...1 . = Data type: Variable
.... ..0. . = Coordinates: Absolute
.... .0.. . = Min/max wraparound: No Wrap
.... 0... . = Physical relationship to data: Linear
...0 .... . = Preferred state: Preferred State
..0. .... . = Has null position: No Null position
.0.. .... . = (Non)-volatile: Non Volatile
0... .... . = Bits or bytes: Buffered bytes (default, no second byte present)
Main item (End collection)
Header
.... ..00 = bSize: 0 bytes (0)
.... 00.. = bType: Main (0)
1100 .... = bTag: End collection (0xc)
Main item (End collection)
Header
.... ..00 = bSize: 0 bytes (0)
.... 00.. = bType: Main (0)
1100 .... = bTag: End collection (0xc)
当您解码 HID 描述符时,它将显示数据包格式。不幸的是,在这种情况下,用法页面是 vendor-defined,因此无法准确说明每种用法是如何解释的。
我使用 hidrdd 解码了它(免责声明:我写了它,但它是免费开源的,所以我没有利益冲突)作为:
//--------------------------------------------------------------------------------
// Decoded Application Collection
//--------------------------------------------------------------------------------
/*
06 A0FF (GLOBAL) USAGE_PAGE 0xFFA0 Vendor-defined
09 01 (LOCAL) USAGE 0xFFA00001 <-- Warning: Undocumented usage (document it by inserting 0001 into file FFA0.conf)
A1 01 (MAIN) COLLECTION 0x01 Application (Usage=0xFFA00001: Page=Vendor-defined, Usage=, Type=) <-- Error: COLLECTION must be preceded by a known USAGE
09 02 (LOCAL) USAGE 0xFFA00002 <-- Warning: Undocumented usage (document it by inserting 0002 into file FFA0.conf)
A1 00 (MAIN) COLLECTION 0x00 Physical (Usage=0xFFA00002: Page=Vendor-defined, Usage=, Type=) <-- Error: COLLECTION must be preceded by a known USAGE
06 A1FF (GLOBAL) USAGE_PAGE 0xFFA1 Vendor-defined
09 03 (LOCAL) USAGE 0xFFA10003 <-- Warning: Undocumented usage (document it by inserting 0003 into file FFA1.conf)
09 04 (LOCAL) USAGE 0xFFA10004 <-- Warning: Undocumented usage (document it by inserting 0004 into file FFA1.conf)
15 80 (GLOBAL) LOGICAL_MINIMUM 0x80 (-128)
25 7F (GLOBAL) LOGICAL_MAXIMUM 0x7F (127)
35 00 (GLOBAL) PHYSICAL_MINIMUM 0x00 (0) <-- Info: Consider replacing 35 00 with 34
45 FF (GLOBAL) PHYSICAL_MAXIMUM 0xFF (-1)
75 08 (GLOBAL) REPORT_SIZE 0x08 (8) Number of bits per field
95 08 (GLOBAL) REPORT_COUNT 0x08 (8) Number of fields
81 02 (MAIN) INPUT 0x00000002 (8 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap <-- Error: PHYSICAL_MAXIMUM (-1) is less than PHYSICAL_MINIMUM (0)
09 05 (LOCAL) USAGE 0xFFA10005 <-- Warning: Undocumented usage (document it by inserting 0005 into file FFA1.conf)
09 06 (LOCAL) USAGE 0xFFA10006 <-- Warning: Undocumented usage (document it by inserting 0006 into file FFA1.conf)
15 80 (GLOBAL) LOGICAL_MINIMUM 0x80 (-128) <-- Redundant: LOGICAL_MINIMUM is already -128
25 7F (GLOBAL) LOGICAL_MAXIMUM 0x7F (127) <-- Redundant: LOGICAL_MAXIMUM is already 127
35 00 (GLOBAL) PHYSICAL_MINIMUM 0x00 (0) <-- Redundant: PHYSICAL_MINIMUM is already 0 <-- Info: Consider replacing 35 00 with 34
45 FF (GLOBAL) PHYSICAL_MAXIMUM 0xFF (-1) <-- Redundant: PHYSICAL_MAXIMUM is already -1
75 08 (GLOBAL) REPORT_SIZE 0x08 (8) Number of bits per field <-- Redundant: REPORT_SIZE is already 8
95 08 (GLOBAL) REPORT_COUNT 0x08 (8) Number of fields <-- Redundant: REPORT_COUNT is already 8
91 02 (MAIN) OUTPUT 0x00000002 (8 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap <-- Error: PHYSICAL_MAXIMUM (-1) is less than PHYSICAL_MINIMUM (0)
C0 (MAIN) END_COLLECTION Physical <-- Warning: Physical units are still in effect PHYSICAL(MIN=0,MAX=-1) UNIT(0x,EXP=0)
C0 (MAIN) END_COLLECTION Application <-- Warning: Physical units are still in effect PHYSICAL(MIN=0,MAX=-1) UNIT(0x,EXP=0)
*/
//--------------------------------------------------------------------------------
// Vendor-defined inputReport (Device --> Host)
//--------------------------------------------------------------------------------
typedef struct
{
// No REPORT ID byte
// Collection: CA: CP:
int8_t VEN_0003; // Usage 0xFFA10003: , Value = -128 to 127, Physical = (Value + 128) x -1 / 255
int8_t VEN_0004[7]; // Usage 0xFFA10004: , Value = -128 to 127, Physical = (Value + 128) x -1 / 255
} inputReport_t;
//--------------------------------------------------------------------------------
// Vendor-defined outputReport (Device <-- Host)
//--------------------------------------------------------------------------------
typedef struct
{
// No REPORT ID byte
// Collection: CA: CP:
int8_t VEN_0005; // Usage 0xFFA10005: , Value = -128 to 127, Physical = (Value + 128) x -1 / 255
int8_t VEN_0006[7]; // Usage 0xFFA10006: , Value = -128 to 127, Physical = (Value + 128) x -1 / 255
} outputReport_t;
如您所见,上述 HID 描述符存在一些问题(例如,物理最大值 45 FF 为 -1,但我认为它们意味着 255 - 应表示为 46 FF 00)但问题仍然存在它没有告诉您有关用法的含义。顺便说一句,即使是 Wireshark 也没有正确报告逻辑最小值:15 80 是 -128 而不是 128。
我们只能从中看出报告有 8 个字节长,第一个字节似乎是某种 id(好吧,它的用法与其余 7 个字节不同)。
只有供应商的驱动程序知道如何解释报告,但如果在受控条件下获得足够数量的 Wireshark 数据包捕获,您可能能够对可行的解释进行逆向工程。
抱歉,这是我能做的最好的了。
我也买了分贝仪,刚好适合你的型号。我目前正在尝试将此代码移植到 bash 脚本:https://github.com/dobra-noc/gm1356 它适用于我的设备(顺便说一句,它甚至不是 gm1356)我猜它对你有用也是。
我有一个带 USB 的数字声级计(声压计)GM1356。 Windows 上有一些软件可以处理它,但我没有 CD,也无法在 Internet 上使用。我想要做的是读取它关于 Linux 上当前噪音水平的数据。
我发现已经有一个库允许我使用我知道的语言(ruby、libusb)来执行此操作。在下一步中,我安装了 wireshark 来检查它发送给 pc 的内容。它不会发送太多。我发现的最有趣的数据包是 DESCRIPTOR HID Report
。我想知道接下来我应该采取什么步骤来阅读我感兴趣的数据。我如何确定我应该发送哪些请求来获取它?
HID Report
Global item (Usage)
Header
.... ..10 = bSize: 2 bytes (2)
.... 01.. = bType: Global (1)
0000 .... = bTag: Usage (0x0)
Usage page: [Vendor-defined] (0xffa0)
Local item (Usage)
Header
.... ..01 = bSize: 1 byte (1)
.... 10.. = bType: Local (2)
0000 .... = bTag: Usage (0x0)
Usage: [Vendor-defined] (0xffa00001)
Main item (Collection)
Header
.... ..01 = bSize: 1 byte (1)
.... 00.. = bType: Main (0)
1010 .... = bTag: Collection (0xa)
Collection type: Application (0x01)
Local item (Usage)
Header
.... ..01 = bSize: 1 byte (1)
.... 10.. = bType: Local (2)
0000 .... = bTag: Usage (0x0)
Usage: [Vendor-defined] (0xffa00002)
Main item (Collection)
Header
.... ..01 = bSize: 1 byte (1)
.... 00.. = bType: Main (0)
1010 .... = bTag: Collection (0xa)
Collection type: Physical (0x00)
Global item (Usage)
Header
.... ..10 = bSize: 2 bytes (2)
.... 01.. = bType: Global (1)
0000 .... = bTag: Usage (0x0)
Usage page: [Vendor-defined] (0xffa1)
Local item (Usage)
Header
.... ..01 = bSize: 1 byte (1)
.... 10.. = bType: Local (2)
0000 .... = bTag: Usage (0x0)
Usage: [Vendor-defined] (0xffa10003)
Local item (Usage)
Header
.... ..01 = bSize: 1 byte (1)
.... 10.. = bType: Local (2)
0000 .... = bTag: Usage (0x0)
Usage: [Vendor-defined] (0xffa10004)
Global item (Logical minimum)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
0001 .... = bTag: Logical minimum (0x1)
Logical minimum: 128
Global item (Logical maximum)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
0010 .... = bTag: Logical maximum (0x2)
Logical maximum: 127
Global item (Physical minimum)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
0011 .... = bTag: Physical minimum (0x3)
Physical minimum: 0
Global item (Physical maximum)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
0100 .... = bTag: Physical maximum (0x4)
Physical maximum: 255
Global item (Report size)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
0111 .... = bTag: Report size (0x7)
Report size: 8
Global item (Report count)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
1001 .... = bTag: Report count (0x9)
Report count: 8
Main item (Input)
Header
.... ..01 = bSize: 1 byte (1)
.... 00.. = bType: Main (0)
1000 .... = bTag: Input (0x8)
.... .... 0 = Data/constant: Data
.... ...1 . = Data type: Variable
.... ..0. . = Coordinates: Absolute
.... .0.. . = Min/max wraparound: No Wrap
.... 0... . = Physical relationship to data: Linear
...0 .... . = Preferred state: Preferred State
..0. .... . = Has null position: No Null position
.0.. .... . = [Reserved]: False
0... .... . = Bits or bytes: Buffered bytes (default, no second byte present)
Local item (Usage)
Header
.... ..01 = bSize: 1 byte (1)
.... 10.. = bType: Local (2)
0000 .... = bTag: Usage (0x0)
Usage: [Vendor-defined] (0xffa10005)
Local item (Usage)
Header
.... ..01 = bSize: 1 byte (1)
.... 10.. = bType: Local (2)
0000 .... = bTag: Usage (0x0)
Usage: [Vendor-defined] (0xffa10006)
Global item (Logical minimum)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
0001 .... = bTag: Logical minimum (0x1)
Logical minimum: 128
Global item (Logical maximum)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
0010 .... = bTag: Logical maximum (0x2)
Logical maximum: 127
Global item (Physical minimum)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
0011 .... = bTag: Physical minimum (0x3)
Physical minimum: 0
Global item (Physical maximum)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
0100 .... = bTag: Physical maximum (0x4)
Physical maximum: 255
Global item (Report size)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
0111 .... = bTag: Report size (0x7)
Report size: 8
Global item (Report count)
Header
.... ..01 = bSize: 1 byte (1)
.... 01.. = bType: Global (1)
1001 .... = bTag: Report count (0x9)
Report count: 8
Main item (Output)
Header
.... ..01 = bSize: 1 byte (1)
.... 00.. = bType: Main (0)
1001 .... = bTag: Output (0x9)
.... .... 0 = Data/constant: Data
.... ...1 . = Data type: Variable
.... ..0. . = Coordinates: Absolute
.... .0.. . = Min/max wraparound: No Wrap
.... 0... . = Physical relationship to data: Linear
...0 .... . = Preferred state: Preferred State
..0. .... . = Has null position: No Null position
.0.. .... . = (Non)-volatile: Non Volatile
0... .... . = Bits or bytes: Buffered bytes (default, no second byte present)
Main item (End collection)
Header
.... ..00 = bSize: 0 bytes (0)
.... 00.. = bType: Main (0)
1100 .... = bTag: End collection (0xc)
Main item (End collection)
Header
.... ..00 = bSize: 0 bytes (0)
.... 00.. = bType: Main (0)
1100 .... = bTag: End collection (0xc)
当您解码 HID 描述符时,它将显示数据包格式。不幸的是,在这种情况下,用法页面是 vendor-defined,因此无法准确说明每种用法是如何解释的。
我使用 hidrdd 解码了它(免责声明:我写了它,但它是免费开源的,所以我没有利益冲突)作为:
//--------------------------------------------------------------------------------
// Decoded Application Collection
//--------------------------------------------------------------------------------
/*
06 A0FF (GLOBAL) USAGE_PAGE 0xFFA0 Vendor-defined
09 01 (LOCAL) USAGE 0xFFA00001 <-- Warning: Undocumented usage (document it by inserting 0001 into file FFA0.conf)
A1 01 (MAIN) COLLECTION 0x01 Application (Usage=0xFFA00001: Page=Vendor-defined, Usage=, Type=) <-- Error: COLLECTION must be preceded by a known USAGE
09 02 (LOCAL) USAGE 0xFFA00002 <-- Warning: Undocumented usage (document it by inserting 0002 into file FFA0.conf)
A1 00 (MAIN) COLLECTION 0x00 Physical (Usage=0xFFA00002: Page=Vendor-defined, Usage=, Type=) <-- Error: COLLECTION must be preceded by a known USAGE
06 A1FF (GLOBAL) USAGE_PAGE 0xFFA1 Vendor-defined
09 03 (LOCAL) USAGE 0xFFA10003 <-- Warning: Undocumented usage (document it by inserting 0003 into file FFA1.conf)
09 04 (LOCAL) USAGE 0xFFA10004 <-- Warning: Undocumented usage (document it by inserting 0004 into file FFA1.conf)
15 80 (GLOBAL) LOGICAL_MINIMUM 0x80 (-128)
25 7F (GLOBAL) LOGICAL_MAXIMUM 0x7F (127)
35 00 (GLOBAL) PHYSICAL_MINIMUM 0x00 (0) <-- Info: Consider replacing 35 00 with 34
45 FF (GLOBAL) PHYSICAL_MAXIMUM 0xFF (-1)
75 08 (GLOBAL) REPORT_SIZE 0x08 (8) Number of bits per field
95 08 (GLOBAL) REPORT_COUNT 0x08 (8) Number of fields
81 02 (MAIN) INPUT 0x00000002 (8 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap <-- Error: PHYSICAL_MAXIMUM (-1) is less than PHYSICAL_MINIMUM (0)
09 05 (LOCAL) USAGE 0xFFA10005 <-- Warning: Undocumented usage (document it by inserting 0005 into file FFA1.conf)
09 06 (LOCAL) USAGE 0xFFA10006 <-- Warning: Undocumented usage (document it by inserting 0006 into file FFA1.conf)
15 80 (GLOBAL) LOGICAL_MINIMUM 0x80 (-128) <-- Redundant: LOGICAL_MINIMUM is already -128
25 7F (GLOBAL) LOGICAL_MAXIMUM 0x7F (127) <-- Redundant: LOGICAL_MAXIMUM is already 127
35 00 (GLOBAL) PHYSICAL_MINIMUM 0x00 (0) <-- Redundant: PHYSICAL_MINIMUM is already 0 <-- Info: Consider replacing 35 00 with 34
45 FF (GLOBAL) PHYSICAL_MAXIMUM 0xFF (-1) <-- Redundant: PHYSICAL_MAXIMUM is already -1
75 08 (GLOBAL) REPORT_SIZE 0x08 (8) Number of bits per field <-- Redundant: REPORT_SIZE is already 8
95 08 (GLOBAL) REPORT_COUNT 0x08 (8) Number of fields <-- Redundant: REPORT_COUNT is already 8
91 02 (MAIN) OUTPUT 0x00000002 (8 fields x 8 bits) 0=Data 1=Variable 0=Absolute 0=NoWrap 0=Linear 0=PrefState 0=NoNull 0=NonVolatile 0=Bitmap <-- Error: PHYSICAL_MAXIMUM (-1) is less than PHYSICAL_MINIMUM (0)
C0 (MAIN) END_COLLECTION Physical <-- Warning: Physical units are still in effect PHYSICAL(MIN=0,MAX=-1) UNIT(0x,EXP=0)
C0 (MAIN) END_COLLECTION Application <-- Warning: Physical units are still in effect PHYSICAL(MIN=0,MAX=-1) UNIT(0x,EXP=0)
*/
//--------------------------------------------------------------------------------
// Vendor-defined inputReport (Device --> Host)
//--------------------------------------------------------------------------------
typedef struct
{
// No REPORT ID byte
// Collection: CA: CP:
int8_t VEN_0003; // Usage 0xFFA10003: , Value = -128 to 127, Physical = (Value + 128) x -1 / 255
int8_t VEN_0004[7]; // Usage 0xFFA10004: , Value = -128 to 127, Physical = (Value + 128) x -1 / 255
} inputReport_t;
//--------------------------------------------------------------------------------
// Vendor-defined outputReport (Device <-- Host)
//--------------------------------------------------------------------------------
typedef struct
{
// No REPORT ID byte
// Collection: CA: CP:
int8_t VEN_0005; // Usage 0xFFA10005: , Value = -128 to 127, Physical = (Value + 128) x -1 / 255
int8_t VEN_0006[7]; // Usage 0xFFA10006: , Value = -128 to 127, Physical = (Value + 128) x -1 / 255
} outputReport_t;
如您所见,上述 HID 描述符存在一些问题(例如,物理最大值 45 FF 为 -1,但我认为它们意味着 255 - 应表示为 46 FF 00)但问题仍然存在它没有告诉您有关用法的含义。顺便说一句,即使是 Wireshark 也没有正确报告逻辑最小值:15 80 是 -128 而不是 128。
我们只能从中看出报告有 8 个字节长,第一个字节似乎是某种 id(好吧,它的用法与其余 7 个字节不同)。
只有供应商的驱动程序知道如何解释报告,但如果在受控条件下获得足够数量的 Wireshark 数据包捕获,您可能能够对可行的解释进行逆向工程。
抱歉,这是我能做的最好的了。
我也买了分贝仪,刚好适合你的型号。我目前正在尝试将此代码移植到 bash 脚本:https://github.com/dobra-noc/gm1356 它适用于我的设备(顺便说一句,它甚至不是 gm1356)我猜它对你有用也是。