Receivers
The USB dongles that wireless Logitech devices pair to, driven through HID++ 1.0 registers and identified by USB vendor/product ID.
A receiver is the USB dongle that wireless Logitech devices pair to. OpenLogi detects the receiver on its USB/HID channel, then enumerates the devices paired to it.
Unlike device features (which use HID++ 2.0), receivers are driven through
HID++ 1.0 registers and are always addressed at device index 0xFF
(RECEIVER_DEVICE_INDEX). They are identified purely by their USB vendor/product
ID; openlogi-hidpp's receiver::detect() matches the channel's VID/PID
against the known sets and returns a Receiver.
Implementation status
Receiver support in the vendored hidpp crate is deliberately conservative;
public documentation is scarce. Logi Bolt is the most complete (developed and
tested against real hardware); Unifying covers discovery and enumeration but
its pairing/management surface is thinner and welcomes hardware testing.
Detection
| Receiver | VID:PID | Transport |
|---|---|---|
| Logi Bolt | 046D:C548 | HID++ 1.0 registers (BLE-based) |
| Unifying | 046D:C52B, 046D:C532, 046D:C537, 046D:C539 | HID++ 1.0 registers (Unifying / DJ) |
| Lightspeed | 046D:C53F, 046D:C547 | Unifying registers, G-series dongles |
receiver::detect(chan) returns Some(Receiver) for a known dongle, or None
otherwise.
The Lightspeed dongles bundled with G-series devices answer the same HID++
1.0 registers as Unifying, so they are detected, enumerated, routed, and paired
through the Unifying code path; only the user-facing name differs
(Lightspeed Receiver). C53F is the nano receiver of wireless mice such as the
G305, verified against a G305 (paired device wpid 0x4074); C547 ships with
newer devices such as the G915 keyboard and the G502 X LIGHTSPEED, verified
against a G915 (wpid 0x407c). C539 is the Lightspeed gaming receiver, listed
with the Unifying PIDs because it is routed as one. C537 is the Nano receiver
bundled with the G602; it answers the same enumeration and pairing-information
registers, so it routes as a Unifying receiver.
Common API
The Receiver enum wraps the concrete receiver kinds and exposes the shared
surface:
| Item | Description |
|---|---|
Receiver::Bolt(_) / Receiver::Unifying(_) | The detected receiver kind. |
name() | Human-readable name (e.g. "Logi Bolt Receiver"). |
get_unique_id() | A string that uniquely identifies this receiver (serial or equivalent). |
RECEIVER_DEVICE_INDEX (0xFF) | The device index used to address the receiver on the channel. |
Errors surface as ReceiverError: UnknownReceiver, or a wrapped HID++ 1.0
Protocol error.
Logi Bolt
The current Logitech receiver. Bolt is BLE-based, pairs up to 6 devices,
and authenticates new devices with a passkey before pairing. bolt::Receiver
exposes:
| Function | Purpose |
|---|---|
count_pairings() | Number of currently paired devices (offline ones included). |
collect_paired_devices() | Enumerate all paired devices (Vec<DeviceConnection>). |
get_device_pairing_information(index) | Pairing info for one slot (DevicePairingInformation). |
get_device_codename(index) | The device's codename / name. |
get_notification_state() / set_notification_state(..) | Read / enable receiver notifications. |
trigger_device_arrival() | Re-fire DeviceConnection events for all paired devices (enumeration). |
discover_devices(timeout) / cancel_device_discovery() | Start / stop discovery of pairable devices (≤ 60 s). |
pair_device(slot, address, authentication, entropy) | Begin pairing a discovered device. |
unpair_device(index) | Remove a pairing. |
listen() | Subscribe to receiver Events. |
Pairing flow
discover_devices(Some(secs))— the receiver emitsEvent::DeviceDiscoveryDeviceDetails(carrying the deviceaddress,kind,wpid,authentication) andEvent::DeviceDiscoveryDeviceNamefor each nearby device.pair_device(slot, address, authentication, entropy)—entropysets passkey complexity (for mice, the number of left/right clicks the user must enter).- The receiver completes pairing and emits
Event::DeviceConnection.
Events (bolt::Event)
| Variant | When |
|---|---|
DeviceConnection(DeviceConnection) | A device connects / disconnects (requires wireless notifications enabled). |
DeviceDiscoveryStatus { discovery_enabled } | Discovery mode toggles. |
DeviceDiscoveryDeviceDetails { counter, kind, wpid, address, authentication } | A device is discovered (details + address required to pair). |
DeviceDiscoveryDeviceName { .. } | The discovered device's name. |
DeviceKind covers Keyboard, Mouse, Numpad, Presenter, Remote,
Trackball, Touchpad, Tablet, Gamepad, Joystick, Headset (plus
Unknown).
Unifying
The previous-generation receiver. Unifying pairs up to 6 devices over the
proprietary Unifying / DJ protocol; once addressed by their slot index, paired
devices speak HID++ 2.0. unifying::Receiver exposes:
| Function | Purpose |
|---|---|
count_pairings() | Number of paired devices (offline ones included). |
get_receiver_info() | Receiver info, including pairing_slots (ReceiverInfo). |
get_device_pairing_information(index) | Pairing info for one slot (DevicePairingInformation). |
trigger_device_arrival() | Re-fire connection events for online devices (startup enumeration). |
get_unique_id() | Receiver serial / unique id. |
listen() | Subscribe to receiver Events. |
Enumerating paired devices (Rust)
use std::sync::Arc;
use hidpp::{
channel::HidppChannel,
receiver::{self, Receiver},
};
// chan: Arc<HidppChannel> bound to the receiver's HID interface.
let Some(rx) = receiver::detect(Arc::clone(&chan)) else {
return; // not a known Logitech receiver
};
println!("{} — {}", rx.name(), rx.get_unique_id().await?);
match rx {
Receiver::Bolt(bolt) => {
for dev in bolt.collect_paired_devices().await? {
// dev: bolt::DeviceConnection — one paired device
let _ = dev;
}
}
Receiver::Unifying(uni) => {
let events = uni.listen();
uni.trigger_device_arrival().await?; // re-fires DeviceConnection events
while let Ok(event) = events.recv().await {
// handle unifying::Event::DeviceConnection { .. }
let _ = event;
break;
}
}
_ => {}
}No receiver
Bluetooth-direct and wired devices enumerate as their own inventory; no receiver involved. See Connect a device.