Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Thoughts about Android support and nusb #213

Open
wuwbobo2021 opened this issue Oct 23, 2024 · 0 comments
Open

Thoughts about Android support and nusb #213

wuwbobo2021 opened this issue Oct 23, 2024 · 0 comments

Comments

@wuwbobo2021
Copy link

Inspired by kevinmehall/nusb#76, I realized that libusb is a wrapper of OS APIs, and rusb is yet another wrapper around libusb (I don't know why rusb authors have decided to do this).

As claimed by nusb crate description, the new library provides a thinner layer over OS APIs with less internal state; it is licensed in Apache 2.0/MIT instead of LGPL, thus static linkage and LTO are always permitted.

If only the authors of rusb and nusb had worked together and made newer versions of rusb on the nusb code base, improvements to the new library would have been much faster, making it much more popular than the current nusb (merely used by probe-rs and a few small projects?).

It becomes realistic to me after I considered to fork the rusb crate and add support for Android, which is merely an afterthought in libusb, whose authors might have not been interested in JNI. According to https://github.com/libusb/libusb/android/README, all functionalities of libusb are available with root permission. Without root privileges, it requires performing enumeration, permission request and connection creation at Java side, wrapping the file descriptor with libusb_wrap_sys_device() to get the libusb_device_handle (corresponds to rusb::DeviceHandle). What about libusb_device (rusb::Device)? Look into libusb_wrap_sys_device() description:

"Call libusb_init_context with the LIBUSB_OPTION_NO_DEVICE_DISCOVERY option if you want to skip enumeration of USB devices. In particular, this might be needed on Android if you don't have authority to access USB devices in general."

"The system device handle must remain open until libusb_close() is called. The system device handle will not be closed by libusb_close()."

"Internally, this function creates a temporary device and makes it available to you through libusb_get_device(). This device is destroyed during libusb_close(). The device shall not be opened through libusb_open()."

If I define a new struct AndroidContext that implements UsbContext trait, and override default implementations of as_raw(), devices() and open_device_with_vid_pid(), is it enough?

Looking into the rusb::DeviceList that should be returned by devices(), you can find that it's a wrapper of a heap array of libusb_device from libusb, and constructors of DeviceList call libusb_get_device_list(), which should be avoided on Android. The generic parameter of UsbContext type is just useless to me. (In fact, its current usage is to distinguish the Context handled by the caller with the static GlobalContext.)

I gave up the idea of implementing the UsbContext trait. Instead I tried to define some independent UsbManager and UsbDeviceInfo. UsbManager is supposed to do enumeration, UsbDeviceInfo collection, connection and rusb::DeviceHandle creation. This would probably make the fork for Android impossible, so I'm working on yet another wrapper of rusb instead.

rusb::DeviceHandle has an unsafe associated function from_libusb() which assumes ownership of the handle and closes it on drop. Wait a minute... are functions of rusb::DeviceHandle::device() valid?

These inconsistences make me suspect the reliability of my rusb Android wrapper (unfinished at this moment), and I think it will be a temporary solution before Android support is added for nusb, of which the functionality is not limited by libusb written in C, and even adding WebUSB support is possible (kevinmehall/nusb#83).

Currently, I'm more familiar with rusb instead of asynchronous programming. I'll provide a link to my Android minimal CDC-ACM driver crate (which is unimplemented in Android OS), with the rusb wrapper as its private module. Hopefully someone will do it for nusb.

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

No branches or pull requests

1 participant