# What Is the Role of the `openlogi-device-registry` Crate in OpenLogi?

> Discover the `openlogi-device-registry` crate's role in OpenLogi. It centralizes hardware identity and USB identifiers for Logitech devices, enabling efficient driver mapping without platform IO.

- Repository: [Xuan Zhang/OpenLogi](https://github.com/AprilNEA/OpenLogi)
- Tags: internals
- Published: 2026-09-04

---

**The `openlogi-device-registry` crate serves as a pure hardware-identity registry that centralizes static metadata for Logitech HID++ devices, providing compile-time lookup tables that map USB identifiers to driver implementations without introducing platform-specific IO dependencies.**

The `openlogi-device-registry` crate sits at the foundation of the OpenLogi system's device abstraction layer. As a hardware-identity registry, it consolidates constant descriptor tables for Logitech receivers and LITRA lighting devices, enabling the higher-level device layer to recognize enumerated HID hardware and select appropriate drivers across macOS, Linux, and Windows.

## Core Responsibilities of the Hardware Registry

The crate's primary function is to decouple hardware identification from driver implementation through static data structures.

### Static Device Metadata Management

At its core, the registry maintains compile-time constant tables that define known hardware configurations. The `RECEIVERS` table in [`src/receiver.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/receiver.rs) catalogs Logitech wireless receivers, while the `LITRA_DEVICES` table in [`src/litra.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/litra.rs) indexes compatible lighting hardware. These tables store `ReceiverDescriptor` and `LitraDescriptor` structs containing brand identifiers, protocol versions, and model classifications.

### USB ID to Driver Mapping

The registry translates low-level USB identifiers—vendor IDs, product IDs, usage pages, and usage IDs—into high-level driver identifiers. This mapping eliminates the need for the device layer to hardcode hardware-specific constants, instead relying on the `find_receiver` and `find_litra` lookup functions to resolve the correct driver ID at runtime.

## Registry Architecture and Source Files

The crate's implementation spans three primary source files, each responsible for distinct hardware categories.

### [`src/lib.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/lib.rs) – Entry Point and Vendor Constants

The library root re-exports the registry modules and defines the canonical Logitech vendor ID constant. This file serves as the unified interface through which consuming crates access receiver and LITRA registries without importing submodule paths directly.

### [`src/receiver.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/receiver.rs) – Receiver Descriptor Tables

This file houses the `ReceiverDescriptor` struct and the globally accessible `RECEIVERS` table. The `find_receiver(vendor_id: u16, product_id: u16)` function performs linear searches through the receiver table, returning `Option<&ReceiverDescriptor>` when hardware matches are found. According to the OpenLogi source code, this enables the device layer to identify receiver models and instantiate protocol-specific communication handlers.

### [`src/litra.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/litra.rs) – LITRA Lighting Device Definitions

Similarly, [`src/litra.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/litra.rs) defines the `LitraDescriptor` struct and the `LITRA_DEVICES` lookup table. The `find_litra` function extends the search criteria to include HID usage pages and usage IDs, accommodating the multi-interface nature of LITRA lighting hardware. This granular matching ensures the system distinguishes between standard HID interfaces and lighting control endpoints on composite devices.

## Practical Lookup Patterns

The registry exposes simple functional interfaces for hardware probing. Device enumeration code in `openlogi-device` invokes these lookups during HID device discovery to determine driver compatibility.

Use the `find_receiver` function to identify Logitech wireless receivers by USB vendor and product IDs:

```rust
use openlogi_device_registry::receiver::find_receiver;

fn identify_logitech_receiver(vendor_id: u16, product_id: u16) {
    if let Some(desc) = find_receiver(vendor_id, product_id) {
        println!(
            "Detected receiver: brand={:?}, protocol={:?}",
            desc.brand, desc.protocol
        );
    } else {
        println!("Unknown receiver hardware.");
    }
}

```

For LITRA lighting devices, include usage page and usage ID parameters in the lookup:

```rust
use openlogi_device_registry::litra::find_litra;

fn identify_litra_device(
    vendor_id: u16,
    product_id: u16,
    usage_page: u16,
    usage_id: u16,
) {
    if let Some(desc) = find_litra(vendor_id, product_id, usage_page, usage_id) {
        println!(
            "LITRA device detected: model={:?}, driver_id={}",
            desc.model, desc.driver_id
        );
    } else {
        println!("Device not recognized as LITRA hardware.");
    }
}

```

## Design Philosophy – The IO-Free Constraint

A critical architectural decision in `openlogi-device-registry` is its complete absence of IO operations. By restricting the crate to compile-time data structures and pure lookup functions, the codebase guarantees that importing the registry never pulls in platform-specific dependencies like `hidapi` or USB subsystem bindings.

This design achieves two objectives. First, it permits the GUI layer, agent daemon, and device drivers to share hardware definitions without linking heavyweight IO libraries. Second, it ensures deterministic hardware identification that behaves identically across macOS, Linux, and Windows compilation targets.

## Summary

- **`openlogi-device-registry`** functions as a central hardware-identity registry for Logitech HID++ devices within the OpenLogi ecosystem.
- The crate provides **compile-time lookup tables** in [`src/receiver.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/receiver.rs) and [`src/litra.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/litra.rs) that map USB identifiers to driver implementations.
- **IO-free design** ensures the crate contains only static data, avoiding platform-specific dependencies and enabling cross-platform usage.
- Lookup functions **`find_receiver`** and **`find_litra`** enable the device layer to recognize hardware and select appropriate drivers during HID enumeration.
- The registry architecture separates hardware identification from driver logic, maintaining clean abstraction boundaries between system layers.

## Frequently Asked Questions

### What specific hardware does the `openlogi-device-registry` crate support?

The crate currently maintains descriptor tables for Logitech wireless receivers (via `RECEIVERS` in [`src/receiver.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/receiver.rs)) and LITRA lighting devices (via `LITRA_DEVICES` in [`src/litra.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/litra.rs)). Each table contains structs defining hardware capabilities, protocol versions, and driver identifiers for supported peripherals.

### How does the registry avoid platform-specific dependencies?

The crate implements a strict **IO-free** architecture containing only compile-time constants and pure lookup functions. By excluding system calls, HID API bindings, or USB subsystem interactions, `openlogi-device-registry` remains a portable data-only dependency that compiles identically across macOS, Linux, and Windows targets.

### What is the relationship between `openlogi-device-registry` and `openlogi-device`?

The `openlogi-device` crate serves as the device layer that consumes the registry. During HID enumeration, `openlogi-device` queries the registry's `find_receiver` and `find_litra` functions to identify newly connected hardware, then instantiates the appropriate driver implementation based on the returned descriptor metadata.

### How are new Logitech devices added to the registry?

Developers append new entries to the static tables in [`src/receiver.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/receiver.rs) or [`src/litra.rs`](https://github.com/AprilNEA/OpenLogi/blob/main/src/litra.rs), defining structs that specify USB vendor/product IDs, usage pages, and corresponding driver identifiers. Because the data is compile-time constant, adding support requires modifying the source code and rebuilding the crate rather than loading external configuration files.