# Plan: Publish as Multi-Protocol Headset Tool ## Status: DRAFT — awaiting review ## Goal Publish `corsairctl` as an open-source, multi-headset CLI tool under GPLv3. Rename away from "Corsair" trademark. Support additional headset protocols using HeadsetControl (C, GPLv3) as reference. --- ## Phase 1: Rename & License (no functional changes) 1. **Pick a new name** — candidates: - `headsetctl` (clear, follows Linux conventions: `brightnessctl`, `bluetoothctl`) - `hsetctl` (shorter, less likely to collide) - `openheadset` (explicit open-source angle) - Decision needed before anything else — name affects crate name, binary, repo, docs 2. **License file** — ✅ Done (GPLv3 LICENSE + Cargo.toml updated) 3. **Rename crate & binary** — update `Cargo.toml` name, all references in code, CLAUDE.md, README, udev rules, Waybar wrapper, PKGBUILD 4. **Add SPDX headers** — GPLv3 requires license notice in each source file 5. **Clean up repo** — there's a nested `src/corsairctl/` directory that looks like an old copy of the entire repo (has its own `.git/`, `Cargo.toml`, `CLAUDE.md`). Investigate and remove if it's dead weight. --- ## Phase 2: Abstract device layer (architecture) Current state: `BragiDevice` directly uses `hidapi` and the Bragi protocol. Everything is Corsair-specific (VID, PIDs, handshake). Target state: a trait-based backend system so multiple protocols can coexist. ``` src/ ├── backend/ │ ├── mod.rs // Headset trait + DeviceInfo struct │ ├── bragi.rs // Corsair Bragi (current code, extracted) │ ├── steelseries.rs // future │ └── logitech.rs // future ├── hid.rs // generic HID helpers (send/recv/flush) ├── cli.rs ├── output.rs ├── error.rs └── main.rs ``` ### The `Headset` trait ```rust pub trait Headset { fn name(&self) -> &str; fn battery_level(&self) -> Result; fn battery_status(&self) -> Result; fn brightness(&self) -> Option>; // not all headsets have LEDs fn set_brightness(&self, value: u16) -> Option>; fn sidetone(&self) -> Option>; // not all have sidetone fn set_sidetone(&self, value: u8) -> Option>; fn info(&self) -> Result; } ``` ### Auto-detection Scan HID devices, try each backend's `probe()` function: ```rust pub fn detect() -> Result> { // Try Bragi first (checks Corsair VID + known PIDs) // Then SteelSeries, Logitech, etc. } ``` --- ## Phase 3: Port first additional protocol Pick the easiest one from HeadsetControl as proof of concept. Good candidates (simple protocol, popular hardware): - **SteelSeries Arctis Nova 7** — straightforward HID, well-documented in HeadsetControl - **Logitech G PRO X** — also relatively simple Steps per protocol: 1. Study HeadsetControl's C implementation 2. Implement as a Rust module behind the `Headset` trait 3. Add VID/PID to auto-detection 4. Update udev rules generator 5. Test (needs hardware or community testers) --- ## Phase 4: Publish 1. **GitHub repo** — rename or create new repo 2. **README** — features, supported devices, install instructions 3. **crates.io** — publish crate 4. **AUR package** — update PKGBUILD 5. **HeadsetControl community** — announce, invite testers for untested protocols --- ## Phase 5: Upstream contribution to HeadsetControl Contribute Bragi protocol support back to [Sapd/HeadsetControl](https://github.com/Sapd/HeadsetControl). ### Why this is feasible HeadsetControl already has `corsair_void_v2w.hpp` which uses a near-identical protocol pattern to Bragi: multi-step handshake (firmware query → software mode → heartbeat), receiver + headset endpoints, HID buffer flushing with 5ms timeout, sidetone 0-1000 range. The `CorsairDevice` base class provides shared helpers for sidetone mapping, battery parsing, and LED control. ### What a `corsair_bragi.hpp` would contain - New class inheriting from `CorsairDevice` - Bragi-specific PIDs: `0x0A6B` (HS80), potentially HS65, Virtuoso SE - Our Bragi property ID set (from `properties.rs`) - LED brightness support (0-1000, not in existing Corsair implementations) - Init handshake adapted to Bragi's two-phase sequence (receiver → headset) ### Steps 1. Study `corsair_device.hpp` and `corsair_void_v2w.hpp` in detail 2. Write `corsair_bragi.hpp` in C++20, following their patterns 3. Test with our HS80 hardware 4. Open PR with protocol documentation (`docs/bragi-protocol.md`) 5. List all known Bragi PIDs we can find (community input helps here) ### Alternative: documentation-only contribution If writing C++ is too much effort, contribute just the protocol documentation as a PR. HeadsetControl's community can implement it from there. We already have `docs/bragi-protocol.md` which covers the full protocol. --- ## Open Questions - [ ] Final name? - [ ] Should sidetone stay ALSA-based or also go through HID where supported? - [ ] Minimum supported Rust version (MSRV)? - [ ] Do we want a config file for per-device settings? - [ ] The nested `src/corsairctl/` directory — is this an old copy or something active?