Skip to content

Filter out non-APDU interfaces in UsbTransport and other changes related to issue #12 - #14

Merged
yogh333 merged 6 commits into
ledger-community:mainfrom
ImplOfAnImpl:usb_interface_selection
Jan 15, 2026
Merged

Filter out non-APDU interfaces in UsbTransport and other changes related to issue #12#14
yogh333 merged 6 commits into
ledger-community:mainfrom
ImplOfAnImpl:usb_interface_selection

Conversation

@ImplOfAnImpl

@ImplOfAnImpl ImplOfAnImpl commented Nov 12, 2025

Copy link
Copy Markdown
Contributor

Edit: initially I wanted to create several PRs on top of each other, but it seems that GitHub can't do that when PRs come from a fork. So I've put all my changes into a single PR.

I have 4 commits here:

  1. "Filter out non-APDU interfaces in UsbTransport".

    This addresses the "USB interface selection" part of A few issues related to device selection #12.

  2. "Improve BLE device discovery, support new models".

    This addresses the "Bluetooth device selection" part of A few issues related to device selection #12. Also, Flex and NanoGen5 were added to the list of models.

    I've only checked BT connectivity on Nano Gen 5, but since the corresponding UUIDs come from Ledger Live source code, I'm pretty sure it should work for other models too.
    Though additional testing won't hurt of course.

  3. "Replace Error::Unknown with more specific errors".

    Not related to A few issues related to device selection #12. It's just that Error::Unknown is way too vague, so I've added a few more specific variants instead. Also, a couple of Error variants were unused, so I removed them.

  4. "UsbTransport and UsbDevice are no longer Send. Remove explicit "impl !Send" and "impl Send" for UsbTransport/UsbDevice".

    This addresses the last item in A few issues related to device selection #12 - UsbTransport/UsbDevice not being Send but being marked as Send anyway.

    As I've said in the issue, IMO UsbTransport/UsbDevice should be Send. But since I haven't got a reply to that, I decided to go the other way and actually make them non-Send.
    So, ledger-lib no longer uses the async-trait crate; instead, when the Send bound on returned futures is not needed, async functions are declared directly and the corresponding warning
    ("use of async fn in public traits is discouraged as auto trait bounds cannot be specified") is silenced via #[allow(async_fn_in_trait)].
    If the Send bound is needed, then the more verbose syntax fn foo() -> impl Future<...> + Send is used.

    Note that there is also the trait-variant crate whose make macro allows to have both the normal "async fn" syntax in traits and the Send bound on the futures.
    But it looks like the crate is unmaintained and make was producing some weird errors in cases when a trait method had a body. So I guess the verbose syntax is the way.

    I also had to introduce an additional trait NonSendExchange, which is like Exchange but without the Send bound. It's needed because UsbDevice can't implement Exchange.

    Also, just in case, I bumped minimum hidapi version to "2.6" (the previously referenced v2.1 required that only one instance of HidApi can exist at time, this restriction was lifted in later versions).

    P.S. async-trait is still used in other places. Probably I should remove it there too, for consistency?

Comment thread cli/Cargo.toml
edition = "2021"
license = "Apache-2.0"

[features]

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: changes in this file are only needed to be able to override the backend from command line when building ledger-cli (e.g. cargo run --no-default-features --features transport_usb_hidraw --bin ledger-cli -- list)

Comment thread lib/Cargo.toml
transport_ble = [ "btleplug" ]

# Switch libusb backends, `libusb` works better with WSL so we're using that by default
# Switch libusb backends, `libusb` works better with WSL and plain Linux so we're using that by default

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI: I had a situation on my Ubuntu where HidApi::devices_list only returned the FIDO interface and not the APDU one when using the hidraw backend, but it returned both interfaces when using libusb. The issue was solved by physically disconnecting and reconnecting the device. So it looks like hidraw is unreliable in general and not only with WSL.

@ImplOfAnImpl
ImplOfAnImpl marked this pull request as draft November 25, 2025 16:43
@ImplOfAnImpl
ImplOfAnImpl force-pushed the usb_interface_selection branch from 118d970 to 6c116c1 Compare November 25, 2025 16:57
…!Send" and "impl Send" for UsbTransport/UsbDevice.
@ImplOfAnImpl
ImplOfAnImpl force-pushed the usb_interface_selection branch from 6c116c1 to 36673bb Compare November 25, 2025 18:08
@ImplOfAnImpl ImplOfAnImpl changed the title Filter out non-APDU interfaces in UsbTransport Filter out non-APDU interfaces in UsbTransport and other changes related to issue #12 Nov 25, 2025
@ImplOfAnImpl
ImplOfAnImpl marked this pull request as ready for review November 25, 2025 18:12

@yogh333 yogh333 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, could you please run clippy in order to make tCI happy? Thanks

@ImplOfAnImpl

Copy link
Copy Markdown
Contributor Author

could you please run clippy in order to make tCI happy?

Done

@ImplOfAnImpl

Copy link
Copy Markdown
Contributor Author

Are there any plans to merge this?

@ImplOfAnImpl

Copy link
Copy Markdown
Contributor Author

I've pushed one more commit, making futures returned by Device's methods Send, otherwise it becomes unusable in the "normal" async code. This, on the other hand, makes Device unusable with types that only implement NonSendExchange (i.e. UsbDevice), which is kind of ugly. I guess just making UsbTransport/UsbDevice Send would have been a better way.

Also, ledger-lib now uses the async-trait macro again, to work around a compiler bug.

Also, I've updated min Rust version to 1.85, because it's what one of dependencies needs.

@yogh333
yogh333 merged commit c8ed12e into ledger-community:main Jan 15, 2026
4 checks passed
@ImplOfAnImpl
ImplOfAnImpl deleted the usb_interface_selection branch April 15, 2026 17:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants