0x0003 · deviceInformation
Read static device metadata — firmware entity count and version per entity, unit ID, model ID, transport flags, and optional serial number.
Static device metadata: the number of firmware entities and, per entity, the type (main firmware, bootloader, hardware) and version. Newer versions also expose the unit ID, model ID, and serial number.
OpenLogi reads this to identify a connected device and to look up its render and hotspot metadata on assets.openlogi.org.
Spec: Logitech HID++ 2.0 — x0003 deviceInformation (v4).
Function reference
The DeviceInformationFeature wrapper (0x0003) exposes:
Methods
| Function | HID++ fn | Signature | Returns |
|---|---|---|---|
get_device_info | 0 | () | DeviceInformation |
get_fw_info | 1 | (entity_index: u8) | DeviceEntityFirmwareInfo |
get_serial_number | 2 | () | String |
All methods are async and return Result<…, Hidpp20Error>.
Types
DeviceInformation
General information about the device and its capabilities, as returned by get_device_info.
| Field | Type | Description |
|---|---|---|
entity_count | u8 | The number of firmware entities whose version information can be retrieved via get_fw_info. |
unit_id | [u8; 4] | A 4-byte random value serving as a unique identifier (among all devices with the same model_id) for the unit. Always 0 on feature version 0. |
transport | DeviceTransport | A bitfield stating which transport protocols the device supports. Always 0 on feature version 0. |
model_id | [u16; 3] | A 6-byte array serving as the identifier for the device model, containing the application PIDs of the supported transports. Always 0 on feature version 0. |
extended_model_id | u8 | An additional configurable production-line attribute (e.g. device colour). Always 0 on feature version < 2. |
capabilities | DeviceInformationCapabilities | Additional capability flags of this feature. All capabilities flagged as unsupported on feature version < 4. |
DeviceTransport
Bitfield stating which transport protocols the device supports (added in feature version 1).
| Field | Type | Description |
|---|---|---|
usb | bool | Whether the device supports USB. |
e_quad | bool | Whether the device supports eQuad, the protocol used by the Unifying Receiver. |
btle | bool | Whether the device supports Bluetooth Low Energy as used by the Bolt Receiver. |
bluetooth | bool | Whether the device supports Bluetooth. |
DeviceInformationCapabilities
Bitfield stating which additional capabilities of the 0x0003 feature are supported (added in feature version 4).
| Field | Type | Description |
|---|---|---|
serial_number | bool | Whether serial number retrieval via get_serial_number is supported. Always false on feature version < 4. |
DeviceEntityFirmwareInfo
Firmware and version information for a single device entity, as returned by get_fw_info.
| Field | Type | Description |
|---|---|---|
entity_type | DeviceEntityType | The type of the described entity. |
firmware_prefix | String | A 3-letter prefix for the firmware name. |
firmware_number | u8 | The firmware number (decoded from packed BCD). |
revision | u8 | The firmware revision (decoded from packed BCD). |
build | u16 | The firmware build number (decoded from packed BCD). |
active | bool | Whether this entity is the responding and active one. Exactly one entity is active at any given time. |
transport_pid | u16 | The transport protocol PID. Set to the actual PID for the active entity; may be zero for inactive entities. |
extra_version | [u8; 5] | Optional extra versioning information. |
DeviceEntityType
The type of a firmware entity within the device.
| Variant | Value | Description |
|---|---|---|
MainApplication | 0 | Main application firmware entity. |
Bootloader | 1 | Bootloader firmware entity. |
Hardware | 2 | Hardware entity. |
Touchpad | 3 | Touchpad firmware/entity. |
OpticalSensor | 4 | Optical sensor entity. |
Softdevice | 5 | Bluetooth SoftDevice entity. |
RfCompanionMcu | 6 | RF companion MCU entity. |
FactoryApplication | 7 | Factory application firmware entity. |
RgbCustomEffect | 8 | RGB custom effect entity. |
MotorDrive | 9 | Motor drive entity. |
Wire format
All three functions use a 3-byte request payload and return a 16-byte long payload (read via extend_payload()). There are no events for this feature.
get_device_info (fn 0)
Request: [0x00, 0x00, 0x00]
Response (byte → field):
| Byte | Field | Notes |
|---|---|---|
| 0 | entity_count | Number of firmware entities |
| 1–4 | unit_id | 4-byte unique unit identifier; [0,0,0,0] on feature version 0 |
| 5 | (reserved) | Not read by the implementation |
| 6 | transport | Bitfield: bit 3 = USB, bit 2 = eQuad, bit 1 = BTLE, bit 0 = Bluetooth |
| 7–8 | model_id[0] | Big-endian u16; first transport PID |
| 9–10 | model_id[1] | Big-endian u16; second transport PID |
| 11–12 | model_id[2] | Big-endian u16; third transport PID |
| 13 | extended_model_id | Production-line attribute (e.g. colour); 0 on feature version < 2 |
| 14 | capabilities | Bitfield: bit 0 = serial_number; 0 on feature version < 4 |
get_fw_info (fn 1)
Request: [entity_index, 0x00, 0x00]
Response (byte → field):
| Byte | Field | Notes |
|---|---|---|
| 0 | entity_type | DeviceEntityType enum value (u8) |
| 1–3 | firmware_prefix | 3-byte ASCII prefix of the firmware name |
| 4 | firmware_number | Packed BCD u8; decoded automatically |
| 5 | revision | Packed BCD u8; decoded automatically |
| 6–7 | build | Big-endian u16 in packed BCD; decoded automatically |
| 8 | active | Bit 0: true if this entity is currently active |
| 9–10 | transport_pid | Big-endian u16; actual PID for the active entity, may be zero for inactive |
| 11–15 | extra_version | 5-byte optional extra versioning information |
get_serial_number (fn 2)
Request: [0x00, 0x00, 0x00]
Response (byte → field):
| Byte | Field | Notes |
|---|---|---|
| 0–11 | serial number | 12-byte UTF-8 string |
Check DeviceInformationCapabilities::serial_number before calling; the function is only present in feature version 4 and later.
Usage (Rust)
use hidpp::{device::Device, feature::device_information::DeviceInformationFeature};
// mut device: Device, already created via Device::new(channel, index)
device.enumerate_features().await?;
if let Some(feat) = device.get_feature::<DeviceInformationFeature>() {
let info = feat.get_device_info().await?;
println!("entity_count={}, unit_id={:02x?}", info.entity_count, info.unit_id);
for i in 0..info.entity_count {
let fw = feat.get_fw_info(i).await?;
println!("[{}] {:?} {}{:02}.{:02} build={}", i, fw.entity_type,
fw.firmware_prefix, fw.firmware_number, fw.revision, fw.build);
}
if info.capabilities.serial_number {
let serial = feat.get_serial_number().await?;
println!("serial={}", serial);
}
}