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.
Why Per-Link Configuration Is Necessary
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.
The links Table Structure and Implementation
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 3direct:046d:c08d— Direct USB connection (vendor046d, productc08d)
Runtime Population and Persistence
The links table operates in two phases:
- Discovery-time population — When a device comes online, OpenLogi scans available transports and creates or updates
LinkConfigentries for each detected route - Persistence to TOML — The in-memory
BTreeMapserializes toconfig.tomlunderdevices.<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
Creating Default Link Entries
// 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
Applying Per-Link Overrides
// 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:
crates/openlogi-desktop/src/state/scroll.rs— Iterates overdevice.linksto apply per-link scroll sensitivity settingscrates/openlogi-desktop/src/state/devices/tests.rs— Contains unit tests verifying correctlinksentry insertion and retrieval
When a device reconnects, the agent consults the persisted links table to reapply route-specific overrides automatically.
Per-Link vs. Per-Device Settings Resolution
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
linkstable 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.rsuses aBTreeMap<String, LinkConfig>for ordered, persistent storage - Runtime code in
openlogi-desktopleveragesdevice.linksfor 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.
What happens to links entries when a device is disconnected or asleep?
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.
Can users manually edit the links table in config.toml?
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →