# What Communication Protocols Does OpenLogi Use with Logitech Devices?

> Discover the communication protocols OpenLogi uses with Logitech devices, including HID++, raw USB HID, Bluetooth, BLE, and tarpc over Unix sockets.

- Repository: [Xuan Zhang/OpenLogi](https://github.com/AprilNEA/OpenLogi)
- Tags: deep-dive
- Published: 2026-08-21

---

**OpenLogi communicates with Logitech hardware through the HID++ protocol over raw USB HID, Bluetooth Classic, and BLE transports, while using tarpc over Unix sockets for internal inter-process communication.**

OpenLogi is an open-source Rust project that provides advanced management capabilities for Logitech peripherals on Linux and macOS. Unlike generic HID implementations, OpenLogi leverages Logitech's proprietary **HID++** protocol to access device-specific features such as DPI adjustment, SmartShift, and RGB backlighting. The codebase separates low-level hardware communication from high-level application logic through a layered architecture defined in the `openlogi-hidpp` and `openlogi-ipc` crates.

## HID++ Protocol: The Core Communication Layer

Logitech devices expose functionality through **HID++** (Human Interface Device Plus Plus), a proprietary extension of the standard USB HID protocol. OpenLogi implements support for both **HID++ 1.0** (used primarily for receiver-level operations) and **HID++ 2.0** (used for advanced device features).

The protocol operates over multiple physical transports while maintaining a consistent message format. In [`crates/openlogi-hidpp/src/channel.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/channel.rs), the `Channel` struct abstracts these transport differences, providing a unified interface for sending commands and receiving device responses regardless of connection type.

### Transport Layer Implementations

OpenLogi supports three distinct transport mechanisms for HID++ communication, each wrapping the standard HID++ message format:

- **USB Cable**: Direct raw HID access using `/dev/hidraw*` on Linux or `IOHIDManager` on macOS
- **Bluetooth Classic**: Standard Bluetooth HID profile exposed as raw HID nodes
- **Bluetooth Low Energy (BLE)**: Direct BLE HID with extended report lengths for HID++ packets

The transport-specific implementations reside in [`crates/openlogi-hidpp/src/channel/transport.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/channel/transport.rs), which handles the platform-specific I/O while presenting a generic `Transport` trait to the channel layer. This design allows [`crates/openlogi-hidpp/src/channel.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/channel.rs) to remain transport-agnostic when building HID++ command packets.

## Inter-Process Communication Architecture

Beyond hardware communication, OpenLogi requires coordination between its GUI, background agent, and overlay components. For this internal communication, the project uses **tarpc** (a Rust RPC framework) over local Unix sockets rather than HID++.

This IPC layer carries serialized commands and status updates between processes but does not replace the raw HID++ transport to physical devices. The contract is defined in [`crates/openlogi-ipc/src/ipc.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-ipc/src/ipc.rs), where the `OpenLogiService` trait specifies available remote procedures. The background agent, implemented in [`crates/openlogi-agent/src/main.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-agent/src/main.rs), owns the exclusive HID++ channel and exposes it to GUI clients through this RPC interface.

## Implementation Details in the OpenLogi Codebase

The Rust crate structure reflects a clear separation between protocol layers. The `openlogi-hidpp` crate contains the core protocol logic, while `openlogi-hid` provides concrete command builders for specific features.

### Opening HID++ Channels

To establish communication with a Logitech device, OpenLogi first detects the receiver or direct connection, then opens a numbered channel corresponding to the device slot. The `Receiver::detect()` method scans available transports, while `Channel::open()` initializes the HID++ state machine.

```rust
use openlogi_hidpp::channel::Channel;
use openlogi_hidpp::receiver::Receiver;

// Detect a receiver (Unifying, Bolt, etc.) on any HID++ transport
let receiver = Receiver::detect()?;

// Open a channel to a specific device slot (0-255)
let mut channel = Channel::open(&receiver, device_slot)?;

```

### Sending HID++ Commands

Concrete HID++ commands are constructed using typed builders in [`crates/openlogi-hid/src/write.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hid/src/write.rs). These structures handle message framing, checksum calculation, and feature index resolution automatically.

```rust
use openlogi_hid::write::dpi::SetDpi;

// Build the HID++ command
let cmd = SetDpi::new(dpi_x, dpi_y);

// Send it over the previously-opened channel
channel.write(&cmd)?;

```

### IPC Client Usage

GUI applications communicate with the background agent through the tarpc client generated from the IPC contract. This allows sandboxed UI processes to request hardware operations without direct HID++ access.

```rust
use openlogi_ipc::ipc::OpenLogiService;

// The GUI creates a client that talks to the agent
let client = OpenLogiService::new("unix:///tmp/openlogi.sock").await?;

// Request a DPI update for device 3
client.set_dpi(3, 1600, 1600).await?;

```

## Summary

- OpenLogi uses **HID++ 1.0 and 2.0** protocols to communicate directly with Logitech hardware features.
- Hardware connectivity is abstracted through raw **USB HID**, **Bluetooth Classic**, and **BLE** transports implemented in [`crates/openlogi-hidpp/src/channel/transport.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/channel/transport.rs).
- The `Channel` struct in [`crates/openlogi-hidpp/src/channel.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/channel.rs) provides a unified interface for all transport types.
- Application components communicate via **tarpc over Unix sockets**, defined in [`crates/openlogi-ipc/src/ipc.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-ipc/src/ipc.rs), keeping HID++ access centralized in the agent process.
- Command builders in [`crates/openlogi-hid/src/write.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hid/src/write.rs) provide type-safe encapsulation of HID++ message construction.

## Frequently Asked Questions

### What is the HID++ protocol?

HID++ is Logitech's proprietary extension of the standard USB HID protocol that exposes advanced device features like adjustable DPI, smart scrolling, and lighting control. OpenLogi implements HID++ to access these capabilities that standard HID drivers cannot reach.

### Does OpenLogi support both wired and wireless Logitech devices?

Yes. For wired connections, OpenLogi uses raw HID access through `/dev/hidraw*` on Linux or `IOHIDManager` on macOS. For wireless devices, it supports both Bluetooth Classic and Bluetooth Low Energy transports, maintaining the same HID++ command interface across all connection types.

### How does OpenLogi handle communication between the GUI and the background agent?

The GUI and agent communicate via **tarpc**, a Rust RPC framework, over local Unix sockets defined in [`crates/openlogi-ipc/src/ipc.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-ipc/src/ipc.rs). This architecture ensures only the privileged agent process directly accesses HID++ hardware channels, while the GUI sends requests through type-safe RPC calls.

### Which transport is used for Bluetooth Low Energy devices?

BLE devices communicate through the BLE-direct HID transport using extended report lengths to accommodate HID++ packets. This implementation shares the same `Channel` abstraction as USB and Bluetooth Classic connections, with transport-specific logic isolated in [`crates/openlogi-hidpp/src/channel/transport.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/crates/openlogi-hidpp/src/channel/transport.rs).