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

Add support for getting device information from opened device on Linux #102

Merged
merged 11 commits into from
Jan 20, 2025

Conversation

kirisauce
Copy link
Contributor

@kirisauce kirisauce commented Dec 31, 2024

Hi! I'm doing some works on Termux. Termux provides a command termux-usb for accessing USB device. But it give me only a file descriptor, and I need to get some basic information about the device. So I did some works to get information about the device itself from opened device.

New Public APIs

  • fn Device::get_device_descriptor()
  • fn Device::get_device_info()
  • struct descriptors::DeviceDescriptor

I'm sorry for the mistakes I made.

Changelog

20250108-1

  • Removed pub fn device::Device::get_device_info
  • Removed pub fn descriptors::DeviceDescriptor::speed
  • Removed fn descriptors::DeviceDescriptor::format_usb_version
  • Removed fn platform::linux_usbfs::device::LinuxDevice::get_busnum_and_devnum
  • Removed fn enumeration::Speed::from_usb_version
  • Renamed fn platform::linux_usbfs::device::LinuxDevice::get_descriptors to descriptors
  • Adjusted Debug implementation for descriptors::DeviceDescriptor to keep the same output format

20250114-1

  • Add fn platform::linux_usbfs::usbfs::get_speed
  • Add fn platform::linux_usbfs::device::LinuxDevice::get_speed
  • Add pub fn device::Device::get_speed

Note: The type descriptors::DeviceDescriptor is defined as USB standard device descriptor.

Copy link
Owner

@kevinmehall kevinmehall left a comment

Choose a reason for hiding this comment

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

Device descriptor is a good addition. It would be nice to have it on all platforms, but that can be added later if you don't have easy access to macOS and Windows.

I'm not sure the API to get DeviceInfo is a good idea. Pretty much all the useful information is exposed in the device descriptor here.

For Android, using Java APIs to enumerate devices to populate DeviceInfo before opening a device is probably a better idea: #86 (comment)

Comment on lines 373 to 384

#[allow(dead_code)] // not used on all platforms
pub(crate) fn from_usb_version(ver: u16) -> Option<Self> {
match ver {
0x0100 => Some(Speed::Low),
0x0110 => Some(Speed::Full),
0x0200 | 0x0210 => Some(Speed::High),
0x0300 => Some(Speed::Super),
0x0310 | 0x0320 => Some(Speed::SuperPlus),
_ => None,
}
}
Copy link
Owner

Choose a reason for hiding this comment

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

You can't assume the speed from the USB version. Plenty of Full Speed devices devices specify 0x0200, or 0x0210 if they support BOS. I'd rather return None than take a wild guess like this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thank your for the correction! I will change them later.

src/device.rs Outdated Show resolved Hide resolved
src/descriptors.rs Outdated Show resolved Hide resolved
src/device.rs Outdated Show resolved Hide resolved
@kirisauce kirisauce force-pushed the dev branch 2 times, most recently from 3a17c2b to 28cd2b7 Compare January 8, 2025 05:03
@kirisauce
Copy link
Contributor Author

kirisauce commented Jan 8, 2025

@kevinmehall Besides, I'm trying implementing a new feature that could get device speed from an opened device through an ioctl USBDEVFS_GET_SPEED. But one of its return value USB_SPEED_WIRELESS (defined in linux/usb/ch9.h) has no corresponding value in enumeration::Speed. According to the comment, it is called usb2.5, and should it be Speed::Full, Speed::High or others?

enum usb_device_speed {
	USB_SPEED_UNKNOWN = 0,			/* enumerating */
	USB_SPEED_LOW, USB_SPEED_FULL,		/* usb 1.1 */
	USB_SPEED_HIGH,				/* usb 2.0 */
	USB_SPEED_WIRELESS,			/* wireless (usb 2.5) */
	USB_SPEED_SUPER,			/* usb 3.0 */
	USB_SPEED_SUPER_PLUS,			/* usb 3.1 */
};

@kevinmehall
Copy link
Owner

That seems like a better approach. It should probably return Option to cover the case of newer speeds introduced that we don't know about yet, or failure of the ioctl, and you can use that to leave USB_SPEED_WIRELESS undefined. Support for Wireless USB was removed in kernel 5.7 and was long dead before that.

kirisauce and others added 9 commits January 13, 2025 22:58
This is done through an ioctl `USBDEVFS_GET_SPEED`. Judging from
the kernel souce code, it just returns a cached value, and should
not make any request to the device.
Unlike the Configuration descriptor, it does not contain nested
descriptors.

It's also made infallible, because the kernel wouldn't enumerate
the device without it.
We'll log if the ioctl failed, but there's probably not a use case to
determine why it failed to justify Result<Option<>>. It'll be
infallible (besides unknown values) on other platforms.
@kevinmehall
Copy link
Owner

Thanks!

Made some API tweaks and added Windows and macOS implementations of these APIs.

@kevinmehall kevinmehall merged commit a34c449 into kevinmehall:main Jan 20, 2025
8 checks passed
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