What Is the Purpose of the `links` Table in OpenLogi Configuration?

The links table in OpenLogi's configuration maps each physical device to its distinct transport routes and stores per-link capabilities and user overrides, enabling accurate device management across multiple connection methods.

The OpenLogi project is an open-source control suite for Logitech devices that handles complex scenarios where a single physical device appears through multiple transports. The links table, defined in crates/openlogi-core/src/config/device.rs, serves as the architectural solution that makes this possible.

Modern Logitech peripherals often connect through multiple pathways simultaneously. A Logitech G502 LIGHTSPEED mouse, for example, may appear:

  • Via its proprietary LIGHTSPEED receiver (wireless dongle)
  • Via a direct USB cable connection

Each transport exposes different capabilities and requires independent user settings. The Hi-Res Wheel might behave differently over wireless versus wired connections. DPI preferences, scroll inversion, lighting profiles, and SmartShift thresholds may need per-transport tuning.

Without the links table, OpenLogi would collapse these distinct identities into a single flat record, causing configuration conflicts and capability misreporting.

In crates/openlogi-core/src/config/device.rs, the DeviceConfig struct contains the links field at line 71:

pub struct DeviceConfig {
    // ... other fields ...
    pub links: BTreeMap<String, LinkConfig>,
}

The BTreeMap uses canonical route identifiers (DeviceStableId::route_key) as keys. Each LinkConfig entry, defined at line 84 in the same file, contains:

  • capabilities — Features actually observed on that specific route (e.g., "wired", wireless-specific attributes)
  • overrides — User-defined settings that shadow device-level defaults for this transport only

Route Keys: The Stable Identifier

The route key solves a critical persistence problem: devices sleep, disconnect, and reconnect, but their transport routes remain stable. This allows OpenLogi to reconstruct device state without rediscovery on every launch.

Route key formats follow predictable patterns:

  • receiver:aabbccdd:slot:3 — Wireless receiver on channel 3
  • direct:046d:c08d — Direct USB connection (vendor 046d, product c08d)

Runtime Population and Persistence

The links table operates in two phases:

  1. Discovery-time population — When a device comes online, OpenLogi scans available transports and creates or updates LinkConfig entries for each detected route
  2. Persistence to TOML — The in-memory BTreeMap serializes to config.toml under devices.<id>.links.<route_key> paths

This dual-phase approach ensures that offline configuration editing remains possible — users can tweak settings for a sleeping device, and OpenLogi applies them on next connection.

TOML Configuration Example

From docs/config.example.toml:

[devices."unit:6be9d300".links."receiver:aabbccdd:slot:3"]
capabilities = "wired"

[devices."unit:6be9d300".links."direct:046d:c08d".overrides]
dpi = 1200

Here, DPI is overridden only for the direct USB link, while the receiver link retains device-default DPI behavior.

Practical Code Operations

// From openlogi-core configuration handling
let mut device = config.devices.get_mut("unit:6be9d300").unwrap();
device.links.entry("direct:046d:c08d".to_string())
    .or_default(); // Inserts default LinkConfig with empty overrides, no capabilities
// Override DPI exclusively on the receiver link
device.links.get_mut("receiver:aabbccdd:slot:3")
    .unwrap()
    .overrides.dpi = Some(Dpi::new(1600));

The or_default() pattern ensures idempotent entry creation — repeated discoveries of the same route don't duplicate configuration data.

Integration with Desktop Application

The OpenLogi desktop application consumes device.links for UI rendering and runtime state management:

When a device reconnects, the agent consults the persisted links table to reapply route-specific overrides automatically.

OpenLogi uses a simple shadowing hierarchy:

Priority Source Applies When
1 LinkOverrides for active route Per-link entry exists with explicit value
2 DeviceConfig defaults No link-specific override defined
3 Factory/device-class defaults No configuration present at any level

This ensures that common settings are configured once, while transport-specific exceptions are stored precisely where they apply.

Summary

  • The links table in OpenLogi configuration indexes physical devices by their transport routes, solving the multi-connection peripheral problem
  • Each entry stores measured capabilities and user overrides specific to one transport path
  • Route keys (receiver:..., direct:...) provide stable identifiers that survive device sleep cycles
  • The implementation in crates/openlogi-core/src/config/device.rs uses a BTreeMap<String, LinkConfig> for ordered, persistent storage
  • Runtime code in openlogi-desktop leverages device.links for per-transport UI rendering and automatic setting reapplication

Frequently Asked Questions

How does OpenLogi handle a device connected via both USB and wireless simultaneously?

OpenLogi creates separate LinkConfig entries for each active transport. The links table keys (receiver:aabbccdd:slot:3, direct:046d:c08d) distinguish the routes, and per-link overrides apply independently. The UI typically presents both connections, allowing users to configure settings for each pathway.

Entries persist in config.toml indefinitely. Since route keys are stable identifiers derived from hardware topology rather than runtime handles, OpenLogi can reconstruct device state on reconnection without requiring the device to be present during configuration loading.

Yes. The TOML structure devices.<id>.links.<route_key> with nested capabilities and overrides sections is designed for human readability and editing. Changes take effect on next agent startup or device reconnection.

Where is the LinkConfig struct defined, and what fields does it contain?

LinkConfig is defined at line 84 of crates/openlogi-core/src/config/device.rs. According to the OpenLogi source code, it contains a capabilities field recording observed features and an overrides field of type LinkOverrides storing user-defined DPI, scroll, lighting, and SmartShift settings.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →