调试模拟键盘鼠标花了我接近一周的时间,到处查找资料,结果东平西凑。靠上厕所的灵感,终于调通了,
主要注意的是绝对值坐标和相对坐标的表达不一样
最后在这里找到了答案,感谢21ic tanganrong 大虾的无私奉献,特作记录
鼠标使用绝对坐标,它的描述符的问题 - 书友会论坛 - 21ic电子技术开发论坛
详细解析
HID 报告描述 2_幕色夜行-CSDN博客
/*hid descriptor for a mouse*/
static struct hidg_func_descriptor kvm_mouse_data = {
.subclass = 0, /*NO SubClass*/
.protocol = 2, /*Mouse*/
.report_length = 6, //绝对值是6, 相对值是4不然打死调不通,实际很简单。但是没有全面了解协议是很难发现这些细节的
.report_desc_length = 126,//62,//104,
.report_desc={
#if 0
#else
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x02, // USAGE (Mouse)
0xa1, 0x01, // COLLECTION (Application)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
0x85, 0x01, // REPORT_ID (1)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x03, // USAGE_MAXIMUM (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,Var,Abs)
0x75, 0x05, // REPORT_SIZE (5)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x01, // INPUT (Cnst,Ary,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7f, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x02, // REPORT_COUNT (2)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xc0, // END_COLLECTION
0xc0, // END_COLLECTION
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x02, // USAGE (Mouse)
0xa1, 0x01, // COLLECTION (Application)
0x09, 0x01, // USAGE (Pointer)
0xa1, 0x00, // COLLECTION (Physical)
0x85, 0x02, // REPORT_ID (2)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x03, // USAGE_MAXIMUM (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,Var,Abs)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x05, // REPORT_COUNT (5)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x7f, // LOGICAL_MAXIMUM (32767)
0x35, 0x00, // PHYSICAL_MINIMUM (0)
0x46, 0xff, 0x7f, // PHYSICAL_MAXIMUM (32767)
0x75, 0x10, // REPORT_SIZE (16)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x09, 0x31, // USAGE (Y)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x26, 0xff, 0x7f, // LOGICAL_MAXIMUM (32767)
0x35, 0x00, // PHYSICAL_MINIMUM (0)
0x46, 0xff, 0x7f, // PHYSICAL_MAXIMUM (32767)
0x75, 0x10, // REPORT_SIZE (16)
0x95, 0x01, // REPORT_COUNT (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0xc0, // END_COLLECTION
0xc0 // END_COLLECTION
#endif
}
};
复合键盘鼠标
0x05, 0x01, // Usage Page (Generic Desktop)
0x04 代表是 Global 类的 Usage Page 功能,最位 2 位表示带多少个字节的数据,因为只带1 个数据,所以是 1,跟 0x04 组合起来就是 0x05 了。其他名称的意思都差不多,数值可以参照上一章的Generic Item Format
0x09, 0x02, // Usage (Mouse)
表示这是一个鼠标, Usage 是为了给对方解析数据时有个参照
0xA1, 0x01, // Collection (Application)
0xA1, 0x01 表示 CollectionApplication ; 0xA1, 0x00 表示 Collection Physical.表示下面所包含的是对 Mouse 的解释
0x85, 0x01, // Report Id (1)
该报告对应的 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
总共有 3 个按键
0x15, 0x00, // Logical Minimum (0)
0x25, 0x01, // Logical Maximum (1)
按键的值是 0 和 1,表示放开和按下
0x75, 0x01, // Report Size (1)
0x95, 0x03, // Report Count (3)
有 3 个 1 位,即用 3bits 分别对应三个按键
0x81, 0x02, // Input (Data, Variable,Absolute) - Button states
将这三个位加入本报告的数据中,这三位是可读写的绝对值
0x75, 0x05, // Report Size (5)
0x95, 0x01, // Report Count (1)
定义 1 个 5 位的数据
0x81, 0x01, // Input (Constant) - Padding or Reserved bits
将这个数据添加到本报告的数据中,主要是与前面 3 位组成一个字节,这 5 位是 Constant数据
0x05, 0x01, // Usage Page (Generic Desktop)
0x09, 0x30, // Usage (X)
0x09, 0x31, // Usage (Y)
0x09, 0x38, // Usage (Wheel)
下面定义的是 X,Y,Wheel 三个功能
0x15, 0x81, // Logical Minimum (-127)
0x25, 0x7F, // Logical Maximum (127)
X,Y,Wheel 的取值范围是-127~127
0x75, 0x08, // Report Size (8)
0x95, 0x03, // Report Count (3)
用三个字节来表示 x,y,wheel
0x81, 0x06, // Input (Data, Variable, Relative) - X & Y coordinate
将这三个字节添加到本报告中
0xC0, // End Collection
0xC0, // End Collection
以下是hid鼠标数据的生成,支持相对和绝对坐标鼠标数据
func generateMouseWheelReport(absolute bool, buttons [3]bool, axis [2]int, wheel uint8) (report []byte, err error) {
var outdata [7]byte
if absolute {
outdata[0] = 0x02
} else {
outdata[0] = 0x01
}
if buttons[0] {
outdata[1] |= BUTTON1
}
if buttons[1] {
outdata[1] |= BUTTON2
}
if buttons[2] {
outdata[1] |= BUTTON3
}
if absolute {
binary.LittleEndian.PutUint16(outdata[2:], uint16(axis[0]))
binary.LittleEndian.PutUint16(outdata[4:], uint16(axis[1]))
outdata[6] = wheel
} else {
outdata[2] = uint8(axis[0])
outdata[3] = uint8(axis[1])
}
return outdata[:], nil
}