0x1814 · changeHost
选择当前 Easy-Switch 主机通道,并管理每个主机槽位中的一个持久 cookie 字节。
changeHost 用于选择多主机设备的当前通道。此功能报告通道数量和当前零起始通道。此功能也可读取和写入每个通道中的一个持久 cookie 字节。OpenLogi 用此功能协调已配置的 Easy-Switch 目标设备。
**规格:**Logitech HID++ 2.0 ——changeHost。**交叉核对:**Logi Options+ 2.8(静态分析)、Solaar。用于:Easy-Switch。
函数参考
ChangeHostFeature 实现函数 0~3。此封装不公开函数 4 或未经请求的函数 0 报告。
方法
| 函数 | HID++ fn | 签名 | 返回值 |
|---|---|---|---|
get_host_info | 0 | () | ChangeHostInfo |
set_current_host | 1 | (host: u8) | () |
get_cookies | 2 | (host_count: u8) | Vec<u8> |
set_cookie | 3 | (host: u8, cookie: u8) | () |
所有方法都是 async,并返回 Result<…, Hidpp20Error>。
类型
ChangeHostInfo
get_host_info 返回下列字段。
| 字段 | 类型 | 说明 |
|---|---|---|
host_count | u8 | 可用主机通道的数量。 |
current_host | u8 | 当前零起始主机通道。 |
capabilities | ChangeHostCapabilities | OpenLogi 对函数 0 的字节 2 所作的类型化表示。 |
ChangeHostCapabilities
OpenLogi 将函数 0 的字节 2 公开为此位标志类型。
| 标志 | 位/值 | 说明 |
|---|---|---|
ENHANCED_HOST_SWITCH | 1 << 0 | OpenLogi 对函数 0 标志位 0 的名称。此位与函数 4 的位 0 之间的关系尚未确认。 |
事件
OpenLogi v0.8.15 不公开类型化的 ChangeHost 事件。
| 线格式事件 | HID++ fn | 类型化公开状态 |
|---|---|---|
ChangeHostRequested | 0,未经请求 | 未公开 |
线格式
函数 0~3 使用 3 字节短请求负载。OpenLogi 使用 extend_payload() 读取具有响应的函数。
get_host_info(fn 0)
请求:[0x00, 0x00, 0x00]。
| 字节 | 字段 | 备注 |
|---|---|---|
| 0 | host_count | 主机通道数量。 |
| 1 | current_host | 当前零起始主机通道。 |
| 2 | flags | Options+ 2.8 将此字段称为 flags。OpenLogi 将此字节映射为 ChangeHostCapabilities。 |
OpenLogi 用 from_bits_retain 保留未知位。现有证据不能确认此字节的位 0 等于函数 4 的位 0。
set_current_host(fn 1)
OpenLogi 用 notify 发送此函数,因此不会等待响应。
| 字节 | 字段 | 备注 |
|---|---|---|
| 0 | host | 要选择的零起始主机通道。 |
| 1~2 | 填充 | OpenLogi 写入 0x00。 |
请求:[host, 0x00, 0x00]。
get_cookies(fn 2)
请求:[0x00, 0x00, 0x00]。
| 字节 | 字段 | 备注 |
|---|---|---|
0…host_count - 1 | cookie | 每个主机通道各有一个持久字节,顺序与通道顺序相同。 |
调用方提供 host_count。如果响应短于此数量,OpenLogi 将拒绝响应。OpenLogi 忽略此数量之后的字节。
set_cookie(fn 3)
请求:[host, cookie, 0x00]。
| 字节 | 字段 | 备注 |
|---|---|---|
| 0 | host | 零起始主机通道。 |
| 1 | cookie | 任意的软件定义持久字节。 |
| 2 | 填充 | OpenLogi 写入 0x00。 |
OpenLogi 等待确认并丢弃其负载。固件在新主机配对后清除 cookie 的行为尚未在硬件上验证。
get_capabilities(fn 4)
OpenLogi v0.8.15 不公开此函数。Options+ 2.8 调用函数 4,并将响应的位 0 读取为布尔值。
| 字节 | 字段 | 备注 |
|---|---|---|
| 0,位 0 | capability | Options+ 2.8 读取此位。Options+ 在其联动切换路径中,将此位与不低于 2 的功能版本组合使用。 |
| 0,位 1~7 | / | 未恢复其含义。 |
| 1… | / | 未恢复其布局。 |
未恢复请求参数。此布局来自对 Options+ 2.8 的静态分析。
ChangeHostRequested(未经请求的 fn 0)
此报告与 get_host_info 共用函数 0。Options+ 2.8 只接受 software ID 为 0 且负载至少为 2 字节的未经请求报告。
| 字节 | 字段 | 备注 |
|---|---|---|
| 0 | from | 源零起始主机通道。 |
| 1 | to | 请求的零起始主机通道。 |
| 2… | / | 未恢复其含义。 |
Options+ 2.8 将此报告作为主机切换请求处理。Solaar 已报告硬件发送此通知。OpenLogi v0.8.15 不会解码或转发此报告。
OpenLogi 的用法
OpenLogi 在 host_switch_targets 将键盘关联到目标设备时使用 ChangeHost。会话通过 0x1b04 临时配置可报告的主机控制。OpenLogi 会保存已修改的报告字段,并在退出时恢复。恢复失败时,OpenLogi 保留待重试的恢复任务。
在发送函数 1 前,OpenLogi 会读取每个设备的函数 0。OpenLogi 拒绝不在 0..host_count 内的请求通道。随后,OpenLogi 在可用时查询 0x1815。只有明确的 Empty 状态且 name_len == 0 才会阻止切换。无法读取的状态仍只作参考。
OpenLogi 先准备目标设备,最后才向键盘发送函数 1。这样可在尝试目标切换期间保留共享接收器通道。v0.8.15 的设备层不使用 cookie 函数、函数 4 或 ChangeHostRequested 报告。
未确认的细节
Options+ 2.8 将函数 0 的字节 2 称为 flags。Options+ 也单独调用函数 4 并读取位 0。OpenLogi 将函数 0 的字节公开为 ChangeHostCapabilities::ENHANCED_HOST_SWITCH。公开位定义和硬件抓包均未证明两位具有相同含义。
Options+ 2.8 和 Solaar 都提供了 ChangeHostRequested 的证据。静态分析不能证明哪些型号会发送此报告,也不能证明每次切换都会发送。OpenLogi v0.8.15 改为观察临时 0x1b04 主机控制报告。
Options+ 2.8 可以选择函数 1 的同步或异步路径。OpenLogi 始终发送通知。没有证据表明必须使用同步调用。
Rust 用法
use hidpp::feature::change_host::ChangeHostFeature;
// `device` 是已初始化的可变 HID++ 设备。
device.enumerate_features().await?;
if let Some(feature) = device.get_feature::<ChangeHostFeature>() {
let info = feature.get_host_info().await?;
let target = 1;
if target < info.host_count && target != info.current_host {
feature.set_current_host(target).await?;
}
}