OpenLogi

HID++ 参考

Logitech 用于鼠标、键盘和接收器的厂商协议,以及 OpenLogi 的实现方式:消息格式、错误码、功能发现,以及如何阅读各功能页。

HID++ 是 Logitech 的厂商协议,用来配置鼠标、键盘、灯具和接收器。它运行在 USB HID 和蓝牙 HID 之上。OpenLogi 通过 openlogi-hidpp 直接使用这个协议。openlogi-hidpp 是 hidpp Rust crate 的硬分叉,库名仍是 hidpp,所以各页的代码示例写作 use hidpp::...。

两个代际

  • HID++ 1.0 使用一组固定编号的寄存器。Unifying 和 Bolt 接收器至今仍用它完成 配对和设备枚举。
  • HID++ 2.0 使用一组可发现的功能(feature)。每个功能由一个 16 位 ID 标识, 写作 0xZZZZ,例如 0x2201。现代设备的所有设置都走这一代协议。

消息格式

每条 HID++ 消息都是一个短报告或长报告。OpenLogi 的 HID++ 通信只使用这两种报告。

报告报告 ID长度参数字节数
短报告0x107 字节3
长报告0x1120 字节16

两种报告的前四个字节含义相同:

字节HID++ 2.0HID++ 1.0
0报告 ID(0x10 或 0x11)报告 ID
1设备索引设备索引
2功能索引子 ID(寄存器访问为 0x80–0x83)
3函数 ID(高 4 位)和软件 ID(低 4 位)寄存器地址
4…参数寄存器数据

设备索引选择目标设备。0xFF 寻址接收器本身,或直连设备(蓝牙或 USB 线缆) 自身的功能。配对到接收器上的设备用槽位号寻址,从 1 开始。详见 接收器。

功能索引是每台设备在运行时分配的编号,不是功能 ID。主机通过 0x0000 root 解析一次即可。函数 ID 选择该功能的 某个函数,各功能页写作 fn 0、fn 1 等。

软件 ID

主机用软件 ID 把回复和请求对应起来。请求携带 1–15。设备主动发出的通知携带 0,所以软件 ID 为 0 的报告是事件,不是回复。OpenLogi 按通道分配软件 ID:固定 ID、轮换 ID,或在通道存续期间租用的 ID。租用 ID 保证同一个 HID 节点被并发打开时, 各方不会共用同一个 ID。

回复会原样带回请求的第 1–3 字节。OpenLogi 把回复匹配到这三个字节相同的最早一个 待处理请求。OpenLogi 不会同时发出两个这三个字节相同的请求,因为无线接收器可能乱序 送回它们的回复。

寄存器访问(HID++ 1.0)

子 ID请求
0x80写短寄存器(3 个数据字节)
0x81读短寄存器
0x82写长寄存器(16 个数据字节)
0x83读长寄存器
0x8F错误回复

错误码

HID++ 2.0 错误回复的功能索引为 0xFF。第 3 字节重复失败请求的功能索引,第 4 字节 重复它的函数 ID 与软件 ID 字节,第 5 字节是错误码。OpenLogi 把错误码返回为 Hidpp20Error::Feature(ErrorType)。未知错误码会变成 Hidpp20Error::UnsupportedResponse。

错误码ErrorType含义
0NoError无错误
1Unknown未知错误
2InvalidArgument参数无效
3OutOfRange参数超出范围
4HwError硬件错误
5LogitechInternal固件内部错误
6InvalidFeatureIndex该索引上没有功能
7InvalidFunctionId该功能没有这个函数
8Busy设备忙
9Unsupported不支持该操作

HID++ 1.0 错误回复的子 ID 为 0x8F。第 3、4 字节重复请求的子 ID 和寄存器地址, 第 5 字节是错误码。OpenLogi 把它返回为 Hidpp10Error::RegisterAccess(ErrorType)。

错误码ErrorType(1.0)错误码ErrorType(1.0)
0x00Success0x07Busy
0x01InvalidSubId0x08UnknownDevice
0x02InvalidAddress0x09ResourceError
0x03InvalidValue0x0ARequestUnavailable
0x04ConnectFail0x0BInvalidParamValue
0x05TooManyDevices0x0CWrongPinCode
0x06AlreadyExists

功能发现

2.0 设备通过两个根功能暴露自己的能力:

OpenLogi 探测设备时会枚举它的功能集,然后查询自己支持的功能:设备信息、电量、 DPI、SmartShift 等。功能索引列出所有已收录的功能及其在 OpenLogi 中的状态。

身份标识

线路上有两种标识。接收器有 USB 厂商 ID 和产品 ID,见接收器。 设备通过 0x0003 deviceInformation 报告 model ID。model ID 索引列出所有已知的 model ID。

如何阅读功能页

每个已实现的功能都有一页,章节相同:

  1. 规格行:布局的来源,以及用到该功能的 OpenLogi 页面。
  2. 函数参考:OpenLogi v0.8.15 中 openlogi-hidpp 封装的方法、类型和事件。
  3. 线格式:每个函数和事件的请求、回复字节。多字节字段都注明字节序(BE 或 LE)。
  4. OpenLogi 的用法:设备层的行为,例如先读后写、写后回读校验。
  5. 未确认的细节:各来源说法不一致,或尚无硬件抓包的地方。

有些功能或字段没有公开的 Logitech 规格。这些内容来自对 Logitech 自家软件的静态分析, 目的是实现互操作。此时备注栏会带一个来源标签:

标签来源
Options+ 2.8对 Logi Options+ 2.8 的静态分析。它说明这款软件发送和读取什么,不说明固件怎么做。
G HUB对 Logitech G HUB 的静态分析。局限同上。
Solaar开源实现 Solaar。

没有标签的事实来自 Logitech 的 HID++ 文档,或 OpenLogi 自身经过测试的代码。

归属与版权

本 HID++ 参考是为 OpenLogi 项目原创整理的摘要。它依据公开资料、 hidpp 实现、Solaar,以及为互操作而对 Logitech 软件所做的静态分析,描述 Logitech 的 HID++ 1.0 / 2.0 协议,未复制任何 Logitech 文档或代码。“Logitech”“Unifying”“Logi Bolt”“Options+”“G HUB”为 Logitech 的商标。 OpenLogi 是独立项目,与 Logitech 无关联,亦未获其授权或认可。内容按“现状”提供, 不含任何形式的担保。

本页目录