0x0003 · deviceInformation
读取固件实体、单元与型号标识符、传输标志和可选序列号。
deviceInformation 提供静态身份元数据和固件记录。功能版本会增加单元 ID、传输 PID、扩展型号 ID 和可选序列号能力。OpenLogi 在探测在线设备时使用这些数据。
**规格:**Logitech HID++ 2.0 —— x0003 deviceInformation(v4)。**交叉核对:**Logi Options+ 2.8(静态分析)、Solaar。用于:受支持的设备和
openlogi diag features。
函数参考
DeviceInformationFeature 实现功能版本 0,并读取较高功能版本引入的字段。
方法
| 函数 | HID++ fn | 签名 | 返回值 |
|---|---|---|---|
get_device_info | 0 | () | DeviceInformation |
get_fw_info | 1 | (entity_index: u8) | DeviceEntityFirmwareInfo |
get_serial_number | 2 | () | String |
所有方法都是异步方法,并返回 Result<…, Hidpp20Error>。调用 get_serial_number 前,调用方应该检查 capabilities.serial_number。
类型
DeviceInformation
| 字段 | 类型 | 说明 |
|---|---|---|
entity_count | u8 | 可通过 get_fw_info 读取的固件实体数量。 |
unit_id | [u8; 4] | 每台设备的标识符。功能版本低于 1 时为零。 |
transport | DeviceTransport | 受支持的传输协议。功能版本低于 1 时为零。 |
model_id | [u16; 3] | 最多 3 个应用 PID。功能版本低于 1 时为零。 |
extended_model_id | u8 | 型号的生产线属性,例如颜色。功能版本低于 2 时为零。 |
capabilities | DeviceInformationCapabilities | 功能能力。功能版本低于 4 时为 false。 |
DeviceTransport
| 字段 | 位 | 说明 |
|---|---|---|
usb | 3 | USB 传输协议。 |
e_quad | 2 | eQuad 传输协议,Unifying 接收器使用此协议。 |
btle | 1 | Bluetooth Low Energy 传输协议,Bolt 接收器使用此协议。 |
bluetooth | 0 | Bluetooth 传输协议。 |
DeviceInformationCapabilities
| 字段 | 位 | 说明 |
|---|---|---|
serial_number | 0 | 可以调用 get_serial_number。 |
DeviceEntityFirmwareInfo
| 字段 | 类型 | 说明 |
|---|---|---|
entity_type | DeviceEntityType | 固件实体类型,包括未命名的原始值。 |
firmware_prefix | String | 3-byte UTF-8 固件前缀。无效 UTF-8 返回 UnsupportedResponse。 |
firmware_number | u8 | 解码后版本字段的前两个十进制数字。 |
revision | u8 | 解码后版本字段的后两个十进制数字。 |
build | u16 | 解码后的 4 位 build 值。 |
active | bool | active byte 的位 0。 |
transport_pid | u16 | OpenLogi 对传输特定字节 9–10 的 BE 解释。 |
extra_version | [u8; 5] | OpenLogi 对传输特定字节 11–15 的解释。 |
版本和 build 字段首先按 packed BCD 解码。遇到 non-BCD 字段时,OpenLogi 将 BE 值作为二进制读取,并将其限制为 9999。它将解码后的版本拆为 firmware_number = value / 100 和 revision = value % 100。
DeviceEntityType
| 变体 | 值 | 说明 |
|---|---|---|
MainApplication | 0 | 主应用程序固件。 |
Bootloader | 1 | 引导程序固件。 |
Hardware | 2 | 硬件实体。 |
Touchpad | 3 | 触摸板实体。 |
OpticalSensor | 4 | 光学传感器实体。 |
Softdevice | 5 | Bluetooth SoftDevice 实体。 |
RfCompanionMcu | 6 | RF 协同 MCU 实体。 |
FactoryApplication | 7 | 工厂应用程序实体。 |
RgbCustomEffect | 8 | RGB 自定义效果实体。 |
MotorDrive | 9 | 电机驱动实体。 |
Other(u8) | 其他值 | 没有具名 OpenLogi 变体的原始实体类型。包括协议值 10–15。 |
事件
此功能没有定义事件。
线格式
每个函数都发送 3-byte short payload。OpenLogi 通过 extend_payload() 解析响应,并获得 16-byte payload。
get_device_info(fn 0)
请求:[0x00, 0x00, 0x00]
| 字节 | 字段 | 说明 |
|---|---|---|
| 0 | entity_count | 固件实体数量。 |
| 1–4 | unit_id | 4-byte 单元 ID。 |
| 5 | 保留 | OpenLogi 忽略此字节。 |
| 6 | transport | 位 3–0 依次为 USB、eQuad、BTLE 和 Bluetooth。 |
| 7–8 | model_id[0] | 应用 PID,BE。 |
| 9–10 | model_id[1] | 应用 PID,BE。 |
| 11–12 | model_id[2] | 应用 PID,BE。 |
| 13 | extended_model_id | 扩展型号属性。 |
| 14 | capabilities | 位 0 为 serial_number。 |
| 15 | 尾部 payload | OpenLogi 忽略此字节。 |
三个 PID 槽位按已启用的 Bluetooth、BTLE、eQuad、USB 位顺序排列。设备最多报告 3 个 PID。Solaar。
get_fw_info(fn 1)
请求:[entity_index, 0x00, 0x00]
| 字节 | 字段 | 说明 |
|---|---|---|
| 0 | entity_type | 0 是主应用程序,1 是引导程序,2 是硬件,3–15 是 Other。OpenLogi 将未命名值保留为 Other(u8)。 |
| 1–3 | firmware_prefix | 3 个 UTF-8 字节。 |
| 4–5 | version | 4 位版本字段,BE。标准使用 packed BCD。OpenLogi 接受 non-BCD 二进制值,并限制为 9999。 |
| 6–7 | build | 4 位 build 字段,BE。标准使用 packed BCD。OpenLogi 接受 non-BCD 二进制值,并限制为 9999。 |
| 8 | active | 位 0 是 active 标志。OpenLogi 忽略位 1–7。 |
| 9–15 | transportLayer_Specific_info | 7 个传输特定字节。协议没有在此处定义通用 PID 字段。Options+ 2.8 和 Solaar 将此区域作为原始数据保留。 |
OpenLogi 仅通过拆分字段保留字节 9–15。它将字节 9–10 标为 transport_pid(BE),并将字节 11–15 标为 extra_version。它不提供一个原始 7-byte 字段。
get_serial_number(fn 2)
请求:[0x00, 0x00, 0x00]
| 字节 | 字段 | 说明 |
|---|---|---|
| 0–11 | serial number | 12 个 UTF-8 字节,作为 String 返回。无效 UTF-8 返回 UnsupportedResponse。 |
| 12–15 | 尾部 payload | OpenLogi 忽略这些字节。 |
get_serial_number 在功能版本 4 中引入。封装不强制此版本门控。库存探测会在调用前检查能力位 0。
OpenLogi 的用法
库存探测在功能枚举后读取 get_device_info()。它将 unit ID、传输标志、3 个 PID 和 extended model ID 存入 DeviceModelInfo。它只在能力位 0 已设置时读取序列号。
openlogi diag features 从 0..entity_count 读取每个实体。被拒绝的实体或带无效 UTF-8 前缀的实体会变成 Unreadable 诊断行。通道错误会停止诊断操作。
身份读取失败会将探测标记为不完整。若存在较早的完整缓存条目,OpenLogi 会恢复其型号信息或序列号。这些函数不写入设备状态。
未确认的细节
协议将字节 9–15 称为 transport-layer-specific information。协议没有确认字节 9–10 始终构成 PID。Options+ 2.8 和 Solaar 将该区域作为原始数据保留,而 OpenLogi 使用 transport_pid 和 extra_version 字段。
硬件抓包尚未确认每种实体和传输协议中该区域的含义。因此,本参考分别显示协议字段和当前 OpenLogi API 视图。
Rust 用法
use hidpp::{
device::Device,
feature::device_information::DeviceInformationFeature,
protocol::v20::Hidpp20Error,
};
async fn read_identity(device: &mut Device) -> Result<(), Hidpp20Error> {
device.enumerate_features().await?;
let Some(feature) = device.get_feature::<DeviceInformationFeature>() else {
return Ok(());
};
let info = feature.get_device_info().await?;
println!("unit ID: {:02x?}", info.unit_id);
for entity in 0..info.entity_count {
let firmware = feature.get_fw_info(entity).await?;
println!("{entity}: {:?}, build {}", firmware.entity_type, firmware.build);
}
if info.capabilities.serial_number {
println!("serial: {}", feature.get_serial_number().await?);
}
Ok(())
}