0x8061 · extendedAdjustableReportRate
按连接类型查询最高 8000 Hz 的回报率能力,并读取或设置当前的扩展回报率。
extendedAdjustableReportRate 控制 125 Hz 至 8000 Hz 的高频轮询。它会区分有线 USB 和 Logitech 游戏无线连接,以读取能力和当前速率。设置函数会把速率应用到主机当前使用的连接。
规格: Logitech HID++ 2.0 —— extendedAdjustableReportRate。交叉核对: Logi Options+ 2.8(静态分析)、Solaar。用于: 回报率。
函数参考
ExtendedReportRateFeature 封装器(0x8061,版本 0+)提供 4 个操作。
方法
| 函数 | HID++ fn | 签名 | 返回值 |
|---|---|---|---|
get_device_capabilities | 0 | (connection_type: ConnectionType) | ExtendedReportRateList |
get_actual_report_rate_list | 1 | () | ExtendedReportRateList |
get_report_rate | 2 | (connection_type: ConnectionType) | ExtendedReportRate |
set_report_rate | 3 | (report_rate: ExtendedReportRate) | () |
所有方法均为 async,并返回 Result<…, Hidpp20Error>。
类型
ExtendedReportRateList
此 u16 位标志集表示响应第 2 字节中的速率。
| 标志 | 位或值 | 说明 |
|---|---|---|
HZ_125 | 1 << 0 | 125 Hz,或 8 ms 间隔。 |
HZ_250 | 1 << 1 | 250 Hz,或 4 ms 间隔。 |
HZ_500 | 1 << 2 | 500 Hz,或 2 ms 间隔。 |
HZ_1000 | 1 << 3 | 1000 Hz,或 1 ms 间隔。 |
HZ_2000 | 1 << 4 | 2000 Hz,或 500 µs 间隔。 |
HZ_4000 | 1 << 5 | 4000 Hz,或 250 µs 间隔。 |
HZ_8000 | 1 << 6 | 8000 Hz,或 125 µs 间隔。 |
ConnectionType
此非穷尽枚举为函数 0 和 2 选择连接。
| 变体 | 值 | 说明 |
|---|---|---|
Wired | 0 | 有线 USB。 |
GamingWireless | 1 | Logitech 游戏无线。 |
ExtendedReportRate
此非穷尽枚举供设置函数使用,并由函数 2 返回。
| 变体 | 值 | 说明 |
|---|---|---|
Hz125 | 0 | 125 Hz,或 8 ms。 |
Hz250 | 1 | 250 Hz,或 4 ms。 |
Hz500 | 2 | 500 Hz,或 2 ms。 |
Hz1000 | 3 | 1000 Hz,或 1 ms。 |
Hz2000 | 4 | 2000 Hz,或 500 µs。 |
Hz4000 | 5 | 4000 Hz,或 250 µs。 |
Hz8000 | 6 | 8000 Hz,或 125 µs。 |
事件
封装器未提供 Rust 事件类型。当功能索引匹配 0x8061 且 software ID 为 0 时,非请求的函数 0 报告是回报率变更广播。OpenLogi 随后递增设备设置修订号,并请求重新协调。
线格式
所有 4 个函数都发送 3 字节短请求。OpenLogi 将函数 0 至 2 读取为 16 字节扩展响应。函数 3 只检查 HID++ 确认。
get_device_capabilities(fn 0)
| 请求字节 | 字段 | 备注 |
|---|---|---|
| 0 | connection_type | Wired 为 0。GamingWireless 为 1。 |
| 1~2 | 填充 | OpenLogi 写入 0x00。 |
| 响应字节或位 | 字段 | 备注 |
|---|---|---|
| 0 | 未确认的非速率字节 | Logi Options+ 2.8 不会将此字节纳入速率掩码。OpenLogi 忽略此字节。 |
| 1,位 0~6 | ExtendedReportRateList | 位 0 表示 125 Hz。位 6 表示 8000 Hz。 |
| 1,位 7 | 未分配 | OpenLogi 会在原始位标志值中保留此位。设备层生成可选项时会忽略此位。 |
| 2~15 | 保留 | OpenLogi 忽略这些字节。 |
get_actual_report_rate_list(fn 1)
请求:[0x00, 0x00, 0x00]。3 个字节都是填充。
| 响应字节或位 | 字段 | 备注 |
|---|---|---|
| 0 | 未确认的非速率字节 | Logi Options+ 2.8 不会将此字节纳入速率掩码。OpenLogi 忽略此字节。 |
| 1,位 0~6 | ExtendedReportRateList | 与函数 0 使用相同的单字节掩码。它表示当前连接的速率。 |
| 1,位 7 | 未分配 | OpenLogi 会在原始位标志值中保留此位。设备层生成可选项时会忽略此位。 |
| 2~15 | 保留 | OpenLogi 忽略这些字节。 |
get_report_rate(fn 2)
| 请求字节 | 字段 | 备注 |
|---|---|---|
| 0 | connection_type | Wired 为 0。GamingWireless 为 1。 |
| 1~2 | 填充 | OpenLogi 写入 0x00。 |
| 响应字节 | 字段 | 备注 |
|---|---|---|
| 0 | ExtendedReportRate 判别值 | 0 是 Hz125。6 是 Hz8000。其他值会返回 Hidpp20Error::UnsupportedResponse。 |
| 1~15 | 保留 | OpenLogi 忽略这些字节。 |
set_report_rate(fn 3)
| 请求字节 | 字段 | 备注 |
|---|---|---|
| 0 | ExtendedReportRate 判别值 | 0 是 Hz125。6 是 Hz8000。 |
| 1~2 | 填充 | OpenLogi 写入 0x00。 |
响应:HID++ 确认。OpenLogi 忽略所有响应载荷字节。
回报率变更广播(fn 0)
| 载荷字节 | 字段 | 备注 |
|---|---|---|
| 0~1 | 未确认的事件数据 | Options+ 2.8 在产生事件前要求至少 2 个字节。OpenLogi 不解码或保留这些字节。 |
| 其余字节 | 未确认 | 尚未确定字段布局。OpenLogi 不解码这些字节。 |
OpenLogi 的用法
从 v0.8.14 起,PR #1779 只从响应字节 1 读取速率掩码。字节 0 不会产生伪造的速率能力。从 v0.8.14 起,PR #1808 将此功能连接到设备层、代理 IPC、桌面版的指针标签页、CLI 和库存事件监听器。
设备层优先使用 0x8061,而不是 0x8060。直接设备路由对应 Wired。接收器路由对应 GamingWireless。设备层通过函数 1 读取当前连接的可选项,并通过函数 2 读取当前速率。
OpenLogi 在写入前拒绝当前列表外的速率,并跳过当前已生效的速率。之后,OpenLogi 会独立读取函数 2。不同的值会返回 WriteError::ReportRateNotApplied。确认后的读取失败会保留请求值,作为暂定结果。
库存监听器会识别注册的 0x8061 索引上未匹配且 software ID 为 0 的函数 0 广播。该监听器会递增 settings_revision,排队重新协调,并让客户端重新读取速率。广播不会触发已保存速率的重放。
代理只会在重新连接时重新应用已保存的 report_rate。设备必须具有回报率能力。当前连接还必须声明该速率。OpenLogi 退出时不会重置回报率。有关 GUI、配置和 CLI 的行为,请参阅回报率。
未确认的细节
Logi Options+ 2.8 只从函数 0 和 1 的响应字节 1 读取速率。响应字节 0 的用途仍未确认。OpenLogi 忽略字节 0,而不为它指定速率含义。
Logi Options+ 2.8 只接受至少有 2 个载荷字节的函数 0 通知。尚未恢复载荷字段。OpenLogi 只把报告作为重新读取设备状态的提示。需要硬件捕获才能命名这些字段。
Rust 用法
use hidpp::{
device::Device,
feature::extended_report_rate::{
ConnectionType, ExtendedReportRate, ExtendedReportRateFeature,
},
protocol::v20::Hidpp20Error,
};
async fn set_wired_rate(device: &mut Device) -> Result<(), Hidpp20Error> {
device.enumerate_features().await?;
if let Some(feature) = device.get_feature::<ExtendedReportRateFeature>() {
let supported = feature
.get_device_capabilities(ConnectionType::Wired)
.await?;
if supported.bits() & (1_u16 << u8::from(ExtendedReportRate::Hz1000)) != 0 {
feature.set_report_rate(ExtendedReportRate::Hz1000).await?;
}
}
Ok(())
}