26 Commits
Author SHA1 Message Date
nevaforget 717c54c9c1 chore: harden CI and shipped script, tidy internals (audit remediation)
CI / test (push) Successful in 5s
Update PKGBUILD version / update-pkgver (push) Successful in 0s
A four-axis audit found no HIGH/MEDIUM issues. This addresses the
remaining low-risk items and protects the release path:

- ci: add cargo test + clippy -D warnings gate on master/tags
- ci: reject malformed version tags before the pkgver sed substitution
- fix: move the shipped waybar wrapper's cache/lock to $XDG_RUNTIME_DIR
  (mode-700, no cross-user symlink) instead of predictable /tmp paths
- refactor: find_card() returns the open ALSA mixer, dropping a second
  open; collapse two if-let blocks into edition-2024 let-chains
- docs: record in DECISIONS.md why the audit's "dead code" stays (it
  mirrors the Bragi spec) and why the 5ms HID sleep is left as-is

Bump 0.1.4 -> 0.1.5: the shipped waybar script changes behavior.
v0.1.5
2026-06-23 16:03:35 +02:00
nevaforget 6ec56a7968 fix: enable playback switch when setting sidetone level
The ALSA Sidetone control exposes a playback switch separate from the
volume. Setting only the volume left the switch off, so sidetone stayed
muted regardless of the level. set_level now toggles the switch (level 0
turns it off), and get_level reports 0 when the switch is off instead of
a stale volume reading.
2026-06-23 15:04:24 +02:00
nevaforget 5ebe6f591f docs: translate CLAUDE.md to English
Per the committed=English rule.
2026-06-16 10:46:13 +02:00
nevaforget fb6b212f74 ci: add update-pkgver workflow (tag-trigger) 2026-06-10 18:41:37 +02:00
nevaforget a2ced38e05 fix: reject out-of-range led brightness instead of silently clamping
led accepted any u16 and main.rs clamped to 0..=1000 with no feedback,
inconsistent with sidetone which rejects out-of-range at parse time.
Add a clap range validator (0..=1000) and drop the silent clamp, so
invalid input now fails loudly.

Further quality-audit follow-ups:
- remove dead BragiDevice::open() (no caller; binary uses open_with_verbose)
- add tests: led range validation, format_battery for all status
  variants, waybar "unknown" class

Bump 0.1.2 -> 0.1.3.
2026-06-10 17:51:40 +02:00
nevaforget 8d22299d56 chore: bump version to 0.1.2
Sync Cargo.toml to 0.1.2 and bring PKGBUILD up to date (was stale at
0.1.0): pin the git source to the release tag for reproducible builds
and install the LICENSE file.
v0.1.2
2026-06-10 16:41:42 +02:00
nevaforget be4c392c7f chore: add MIT license, record private-use scope
Add MIT LICENSE file (Cargo.toml already declares MIT). Record in
DECISIONS.md that the open-source publish/rename plan is dropped: the
tool is for personal use, distributed as an Arch package via the private
moonarch repo and used primarily as a Waybar widget.
2026-06-10 16:38:10 +02:00
nevaforget e26c2426bc docs: translate Bragi protocol reference to English
Translate docs/bragi-protocol.md from German to English ahead of
open-source publication. Drop the local reference path and note
additional Bragi devices (HS65, Virtuoso SE).
2026-06-10 16:37:08 +02:00
nevaforget 77a84c8aef docs: add publish plan and decision log
PLAN.md: 5-phase plan to publish as a multi-protocol headset tool
(rename away from Corsair trademark, abstract device layer, port
additional protocols, publish, upstream to HeadsetControl).

DECISIONS.md: rationale for GPLv3 relicense, naming constraints, and
the multi-protocol architecture.
2026-06-10 16:37:08 +02:00
nevaforget 887d38e040 refactor: consume library crate from binary
main.rs declared its own module tree (mod bragi, cli, ...) while lib.rs
re-exported the same modules. The binary recompiled everything without
using the library, producing 9 spurious dead-code warnings for items
that are actually exercised by the integration tests via the library.

Import from the corsairctl library instead. No functional change;
eliminates all 9 warnings.
2026-06-10 16:37:08 +02:00
nevaforget 53061c220b chore: update Cargo.lock for v0.1.1 v0.1.1 2026-04-09 17:17:20 +02:00
nevaforget a2a75ccd08 feat: show sidetone level in Waybar tooltip
Tooltip now shows "HS80: 42% — Discharging | Sidetone: 10/23" when
the ALSA sidetone control is available. Falls back gracefully to
battery-only tooltip when sidetone cannot be read.

Bump version to 0.1.1.
2026-04-09 17:13:41 +02:00
nevaforget a8dc18a1ef fix: Waybar-Modul ausblenden statt "?" wenn Headset nicht erreichbar
Leerer text-Wert lässt Waybar das Modul automatisch verstecken.
Cache-TTL zurück auf 300s.
v0.1.0
2026-03-28 01:35:56 +01:00
nevaforget 631e803981 fix: Audit-Befunde in Protokoll-Parsing, Error-Handling und Eingabe-Validierung
BragiResponse-Felder korrekt zugeordnet (endpoint=raw[1], command=raw[2],
status=raw[3]) gemäß Protokoll-Doku. PropertyNotSupported durch DeviceError
ersetzt, parse_response_validated in device.rs aktiviert, flush() mit
Iterationslimit gegen Endlosschleifen, Sidetone-Range per clap validiert
statt clamp, JSON-Escaping im hidpp-battery-waybar.sh, udev auf uaccess
umgestellt. 52 Tests grün.
2026-03-28 00:37:36 +01:00
nevaforget 74b09b225e chore: makepkg Build-Artefakte in .gitignore 2026-03-27 23:49:10 +01:00
nevaforget 3556912737 fix: Waybar-Wrapper gibt immer Output aus
Fallback-JSON wenn corsairctl fehlschlägt oder Cache leer ist.
flock -w 5 statt -n damit der zweite Prozess wartet statt
sofort aufzugeben. Atomares mv statt direktem Schreiben in Cache.
2026-03-27 23:46:19 +01:00
nevaforget 8da6065d0a feat: Waybar-Wrapper mit File-Locking und Cache
Waybar startet pro Monitor eine eigene corsairctl-Instanz.
Mehrere Prozesse auf demselben HID-Gerät verursachen Response-Mixups.
Der Wrapper cached den JSON-Output für 10s und nutzt flock
damit nur ein Prozess gleichzeitig das Gerät anspricht.
2026-03-27 23:41:08 +01:00
nevaforget 25e16b83a5 fix: Flush vor jeder Property-Query gegen Response-Mixups
Der HID-Puffer kann veraltete Antworten von vorherigen Queries
enthalten. Flush vor jedem send_recv stellt sicher, dass wir
die Antwort auf unsere aktuelle Anfrage lesen.
2026-03-27 23:33:04 +01:00
nevaforget 0baa6a7a4a fix: 5ms Sleep vor HID-Read gegen Response-Mixups
Komplett ohne Sleep kam es sporadisch zu vertauschten Antworten
(267% Batterie = PID-Response statt Battery-Response). 5ms reicht
als Verarbeitungszeit für das Gerät, ist aber 10x schneller als
die ursprünglichen 50ms aus der Python-Referenz.
2026-03-27 23:27:50 +01:00
nevaforget 2a92248851 fix: hidapi auf linux-shared-hidraw Backend für Arch Linux
Das Default-Feature (linux-static-hidraw) linkt statisch gegen
gebundelte hidapi-Quellen. Arch stellt libhidapi-hidraw.so als
Shared Library bereit — linux-shared-hidraw linkt dagegen.
2026-03-27 23:19:39 +01:00
nevaforget d73d512380 feat: PKGBUILD für Arch Linux hinzugefügt
Installiert Binary nach /usr/bin/ und udev-Regel nach
/usr/lib/udev/rules.d/. Dependencies: hidapi, alsa-lib.
2026-03-27 23:16:53 +01:00
nevaforget 2f8c850cca docs: Waybar-Integrations-Beispiel mit Config und Styling 2026-03-27 23:15:13 +01:00
nevaforget a97994b5e0 fix: Audit-Findings behoben (Perf, Security, Quality)
- Sleep vor HID-Reads entfernt — read_timeout reicht als
  Synchronisation, spart ~300ms pro Aufruf
- udev-Regel: MODE 0660 + GROUP plugdev statt world-writable 0666
- Eigener CorsairError::SidetoneNotFound für fehlende ALSA-Controls
- Response-Validierung vorbereitet (parse_response_validated),
  Korrelation noch deaktiviert da Response-Format andere Endpoint-IDs
  nutzt als das Request-Format (0x00/0x01 vs 0x08/0x09)
- Protokoll-Doku zum Response-Format korrigiert
- 18 neue Tests für output.rs (Waybar-JSON Formatierung + Grenzwerte)
2026-03-27 23:11:50 +01:00
nevaforget 0336dffccf fix: BatteryStatus-Mapping empirisch korrigiert
Byte-Zuordnung am echten HS80 verifiziert (Kabel ein/aus):
  0x01 = Charging, 0x02 = Discharging, 0x03 = Low, 0x04 = Full
Weicht vom ckb-next-Mapping ab. Verbose-Flag zeigt jetzt auch
Property-Queries für weitere Diagnose.
2026-03-27 22:16:50 +01:00
nevaforget e78cb3914d fix: Device-Discovery und Sidetone gegen echte Hardware korrigiert
- PID-Filter in find_and_open(), damit nicht die Harpoon-Maus statt
  dem HS80 geöffnet wird
- ALSA Sidetone: Card-Suche über Sidetone-Control statt Kartenname
  (war abgeschnitten zu "Gamin")
- Verbose-Flag (-v) für Debug-Output der Init-Sequenz
2026-03-27 22:10:40 +01:00
nevaforget 3532da5931 feat: initiale Implementierung von corsairctl
Rust CLI-Tool für Corsair Bragi-Geräte (HS80 RGB Wireless, etc.).
Implementiert Protokoll-Kern, HID-Kommunikation, BragiDevice mit
RAII-Lifecycle, CLI-Subcommands (battery, sidetone, led, info, json,
udev), ALSA-Sidetone-Steuerung und Waybar-JSON-Output.

24 Unit-Tests für Packet-Bau, Response-Parsing und Property-Enums.
2026-03-27 17:34:37 +01:00