Replace hidapi with hidra#131
Merged
Merged
Conversation
- actions/checkout v4 -> v6 - actions/cache v4 -> v5 - actions/upload-artifact v4 -> v7 - actions/download-artifact v4 -> v8 - cachix/cachix-action v14 -> v17 - softprops/action-gh-release v2 -> v3 cachix/install-nix-action is already on the latest major (v31).
hidra now exposes one HidApi/HidDevice whose I/O methods return futures
(the nusb-model redesign); there is no separate hidra::usb. Adapt:
- hid.rs: re-export the single hidra::{HidApi, HidDevice} plus MaybeFuture;
the `nusb` feature still selects hidra's nusb backend (now on the unified
type), so the per-OS backend cfg aliasing is gone.
- device_selector.rs / isp_device.rs: drive the now-async open_path,
get_report_descriptor, send_feature_report and get_feature_report calls
with MaybeFuture::wait (the tool stays synchronous).
- Gate the macOS set_open_exclusive call on `not(feature = "nusb")` to match
where hidra exposes it.
- Bump the hidra git pin to the redesigned commit.
Also drops a redundant comment on is_expected_error.
Extract the ISP bootloader protocol, device/platform specs, payload utilities, and ihex helpers into a new sinowealth-isp library crate, and keep the CLI in a sinowealth-kb-tool bin crate. Both live under crates/ in a virtual workspace. The protocol is now expressed as async methods over hidra::HidDevice, so the exact same code drives the native CLI (via MaybeFuture::wait) and a future web flasher (via .await on wasm32 with the WebHID backend). To stay UI- and runtime-free, the library: - reports progress through a caller-supplied Progress callback instead of printing or driving indicatif directly (the CLI maps it onto a progress bar in progress.rs) - waits for the device to settle through a cross-target async sleep (a thread-backed timer on native, setTimeout on the web) instead of thread::sleep - takes an optional separate transfer handle (ISPDevice::new(.., None) on Linux/macOS/WebHID; Some(handle) for the Windows two-collection split), moving that platform branching to the CLI device selector is_expected_error now cfg-gates the native-only HidError::Io variant so it compiles for the web backend. CI gains a wasm build check for sinowealth-isp; the nix build uses singleStep so naersk handles the workspace layout.
sinowealth-isp now exposes only the individual ISP protocol operations (enable_firmware, init_read/read_page, init_write/write_page, erase, reboot) as async methods over hidra::HidDevice. The full read_cycle / write_cycle orchestration, the page loops, progress reporting, and the post-erase/reboot settle delays now live in the CLI (new flasher.rs). This keeps the library free of orchestration, timing, and UI concerns: - erase/reboot no longer sleep; callers insert the delay (the CLI uses thread::sleep, a web app uses setTimeout) - the cross-target async sleep module is gone, so the library no longer needs js-sys/wasm-bindgen/web-sys/wasm-bindgen-futures (or log) - the Progress callback is gone; the CLI drives indicatif directly in its own page loop reboot now returns a Result instead of swallowing errors, so the caller decides how to treat the expected disconnect (the CLI checks is_expected_error on the unwrapped HidError).
The page loops (init_read + read_page x N, init_write + write_page x N) are mechanical protocol with no timing, so they belong in the library as ISPDevice::read/write rather than being duplicated in every consumer. They take a dep-free '&dyn Fn(done, total)' progress callback, so the loop stays in the lib without dragging back any runtime/UI dependency. The CLI flasher (and the web app) now just create their progress bar, pass a callback, and keep owning the surrounding cycle: sequencing, the post-erase/reboot settle delays, and verification.
… single crate Master renamed the package sinowealth-kb-tool -> sinowisp. This branch had split the project into a workspace (sinowealth-isp lib + CLI crate). Resolved by collapsing back into a single `sinowisp` crate that ships both the library (src/lib.rs) and the CLI (src/main.rs): - Moved crates/sinowealth-isp/src/* and crates/sinowealth-kb-tool/src/* into a single src/; tests into tests/. - CLI-only deps (clap, dialoguer, hidparser, indicatif, itertools, md5, simple_logger, log) are gated behind a default `cli` feature; the bin target requires it. This keeps the library buildable on its own for the web (WebHID/wasm) via `--no-default-features`. - Updated the wasm CI job to `cargo build --lib --no-default-features`. - Rewrote intra-crate references sinowealth_isp -> sinowisp. Claude-Session: https://claude.ai/code/session_01MiFqdrz3fGWL2Ue6N8rka2
Removes the git dependency on hidra so the crate can be published to crates.io (cargo publish rejects git deps without a version). Verified the published 0.0.1 compiles for the native CLI, nusb backend, and the wasm/WebHID lib build; `cargo publish --dry-run` now succeeds. Claude-Session: https://claude.ai/code/session_01MiFqdrz3fGWL2Ue6N8rka2
carlossless
added a commit
that referenced
this pull request
Jul 10, 2026
Swaps the `hidapi` dependency for [`hidra`](https://github.com/carlossless/hidra), a pure-Rust HID library. This removes the C/libusb build dependency (no pkg-config or system libusb needed). ## Changes - `Cargo.toml`: `hidapi` -> `hidra` (git dependency, `usb` feature). - New `src/hid.rs`: selects the backend per platform, matching the old `linux-static-libusb` setup. Linux uses hidra's nusb-based `usb` backend; Windows and macOS use the native HID stack. Both expose the same method surface, so the rest of the tool is unchanged. - Mechanical updates in `device_selector.rs`, `isp_device.rs`, `util.rs`: device paths are `&str` instead of `&CStr`, `BusType` is compared directly, and `is_expected_error` matches hidra's typed `HidError` variants instead of backend-specific message strings. ## Testing Verified end-to-end against real hardware (a NuPhy Air60) on all three desktop platforms, performing the full ISP flash cycle: - **Linux** (nusb backend): `list`, `read`, and `write` all produce output byte-identical to the `hidapi` build; firmware read+write round-trips verified by MD5. - **Windows** (native `hid.dll` backend): `list`, `read`, `write` all working. - **macOS** (IOHIDManager backend): `list`, `read`, `write` all working. Unit tests pass. The `tests/list_test.rs` integration tests fail in my environment, but they fail identically on `master` with `hidapi`: they snapshot a stock-firmware keyboard, and my test unit runs custom firmware. They are not affected by this change.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Swaps the
hidapidependency forhidra, a pure-Rust HID library. This removes the C/libusb build dependency (no pkg-config or system libusb needed).Changes
Cargo.toml:hidapi->hidra(git dependency,usbfeature).src/hid.rs: selects the backend per platform, matching the oldlinux-static-libusbsetup. Linux uses hidra's nusb-basedusbbackend; Windows and macOS use the native HID stack. Both expose the same method surface, so the rest of the tool is unchanged.device_selector.rs,isp_device.rs,util.rs: device paths are&strinstead of&CStr,BusTypeis compared directly, andis_expected_errormatches hidra's typedHidErrorvariants instead of backend-specific message strings.Testing
Verified end-to-end against real hardware (a NuPhy Air60) on all three desktop platforms, performing the full ISP flash cycle:
list,read, andwriteall produce output byte-identical to thehidapibuild; firmware read+write round-trips verified by MD5.hid.dllbackend):list,read,writeall working.list,read,writeall working.Unit tests pass. The
tests/list_test.rsintegration tests fail in my environment, but they fail identically onmasterwithhidapi: they snapshot a stock-firmware keyboard, and my test unit runs custom firmware. They are not affected by this change.