OpenLogi

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

ReceiverVID:PIDTransport
Logi Bolt046D:C548HID++ 1.0 registers (BLE-based)
Unifying046D:C52B, 046D:C532, 046D:C537, 046D:C539HID++ 1.0 registers (Unifying / DJ)
Lightspeed046D:C53F, 046D:C547Unifying 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:

ItemDescription
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:

FunctionPurpose
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

  1. discover_devices(Some(secs)) — the receiver emits Event::DeviceDiscoveryDeviceDetails (carrying the device address, kind, wpid, authentication) and Event::DeviceDiscoveryDeviceName for each nearby device.
  2. pair_device(slot, address, authentication, entropy)entropy sets passkey complexity (for mice, the number of left/right clicks the user must enter).
  3. The receiver completes pairing and emits Event::DeviceConnection.

Events (bolt::Event)

VariantWhen
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:

FunctionPurpose
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.

On this page