OpenLogi

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_info0()ChangeHostInfo
set_current_host1(host: u8)()
get_cookies2(host_count: u8)Vec<u8>
set_cookie3(host: u8, cookie: u8)()

所有方法都是 async,并返回 Result<…, Hidpp20Error>。

类型

ChangeHostInfo

get_host_info 返回下列字段。

字段类型说明
host_countu8可用主机通道的数量。
current_hostu8当前零起始主机通道。
capabilitiesChangeHostCapabilitiesOpenLogi 对函数 0 的字节 2 所作的类型化表示。

ChangeHostCapabilities

OpenLogi 将函数 0 的字节 2 公开为此位标志类型。

标志位/值说明
ENHANCED_HOST_SWITCH1 << 0OpenLogi 对函数 0 标志位 0 的名称。此位与函数 4 的位 0 之间的关系尚未确认。

事件

OpenLogi v0.8.15 不公开类型化的 ChangeHost 事件。

线格式事件HID++ fn类型化公开状态
ChangeHostRequested0,未经请求未公开

线格式

函数 0~3 使用 3 字节短请求负载。OpenLogi 使用 extend_payload() 读取具有响应的函数。

get_host_info(fn 0)

请求:[0x00, 0x00, 0x00]。

字节字段备注
0host_count主机通道数量。
1current_host当前零起始主机通道。
2flagsOptions+ 2.8 将此字段称为 flags。OpenLogi 将此字节映射为 ChangeHostCapabilities。

OpenLogi 用 from_bits_retain 保留未知位。现有证据不能确认此字节的位 0 等于函数 4 的位 0。

set_current_host(fn 1)

OpenLogi 用 notify 发送此函数,因此不会等待响应。

字节字段备注
0host要选择的零起始主机通道。
1~2填充OpenLogi 写入 0x00。

请求:[host, 0x00, 0x00]。

get_cookies(fn 2)

请求:[0x00, 0x00, 0x00]。

字节字段备注
0…host_count - 1cookie每个主机通道各有一个持久字节,顺序与通道顺序相同。

调用方提供 host_count。如果响应短于此数量,OpenLogi 将拒绝响应。OpenLogi 忽略此数量之后的字节。

set_cookie(fn 3)

请求:[host, cookie, 0x00]。

字节字段备注
0host零起始主机通道。
1cookie任意的软件定义持久字节。
2填充OpenLogi 写入 0x00。

OpenLogi 等待确认并丢弃其负载。固件在新主机配对后清除 cookie 的行为尚未在硬件上验证。

get_capabilities(fn 4)

OpenLogi v0.8.15 不公开此函数。Options+ 2.8 调用函数 4,并将响应的位 0 读取为布尔值。

字节字段备注
0,位 0capabilityOptions+ 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 字节的未经请求报告。

字节字段备注
0from源零起始主机通道。
1to请求的零起始主机通道。
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?;
    }
}

本页目录