dcuddeback / libusb-rs

A safe Rust wrapper for libusb.
MIT License
199 stars 64 forks source link

control_transfer not implemented #1

Closed r3n4ud closed 9 years ago

r3n4ud commented 9 years ago

control_transfer is not yet implemented in InterfaceHandle althought the binding is present in libusb-sys.

Any plan on that? Do you accept PR on this?

[Slightly OT but related]: xxx_transfer should have been implemented on DeviceHandle, no? I agree it makes sense on InterfaceHandle but

dcuddeback commented 9 years ago

@nibua-r I do plan to support control transfers. The reason it's not in the library yet is that libusb_control_transfer seems too low-level to directly translate to Rust. I was planning to implement each type of control transfer (http://libusb.sourceforge.net/api-1.0/group__misc.html#ga5b5912057c2d7e23b3ed5aa0c20236df) as a separate method. Some of them I think should not be exposed in safe code. For example, the documentation for libusb_set_configuration warns:

You should always use this function rather than formulating your own SET_CONFIGURATION control request.

http://libusb.sourceforge.net/api-1.0/group__dev.html#ga186593ecae576dad6cd9679f45a2aa43

I'd be happy to receive a PR that implements some of the control transfers. Is there a particular control transfer that you're hoping to see implemented?

It looks like your comment got cut off. I'm curious why you think bulk_transfer and interrupt_transfer should be implemented on DeviceHandle. I implemented them on InterfaceHandle because the documentation says that you must claim an interface before performing I/O on its endpoints, but I'm not super happy with the ergonomics of the current design. I'd love to hear your feedback on that.

r3n4ud commented 9 years ago

@dcuddeback I'm new to Rust so I've no enlightened design idea yet :wink: . In fact, I'm playing with Rust by porting a Ruby gem of mine: ligo. This gem provides an implementation of the Android Open Accessory Protocol to enable I/O communication through USB. As a matter of fact, I do use a control_transfer instead of a set_configuration (nothing particular here, I could probably switch to set configuration) but the more important point here is that the Android Accessory Protocol relies on LIBUSB::REQUEST_TYPE_VENDOR control transfers:

The libusb ruby binding implement those transfer methods on the handle, that's the reason why I made this remark. Some usages on how the interface is claimed or used with the handle are here, for discussion.

Cheers! (and thanks for the already efficient enough libusb-rs!!!)

dcuddeback commented 9 years ago

Okay. The vendor requests are a good reason for having a generic control transfer function. For now, I think an almost literal translation of the libusb_control_transfer function will work. I think bmRequestType should be represented as a struct that hides the bitwise operations from the user.

r3n4ud commented 9 years ago

OK. I'll try to get something working for review.

dcuddeback commented 9 years ago

@nibua-r That would be great. Thank you. I will publish a new version of libusb-sys this morning with the definitions from libusb_request_type and libusb_request_recipient, which you'll need to implement the control transfer. I will be out of town for the rest of the week starting tonight, but I will look at anything you send me.

dcuddeback commented 9 years ago

@nibua-r libusb-sys 0.1.1 is now on crates.io. It should have everything you need to implement control transfers. Btw, when it comes to control transfers, I think you're right that it should be implemented on the device handle, because they don't require claiming an interface first.

r3n4ud commented 9 years ago

@dcuddeback :+1:

r3n4ud commented 9 years ago

I got something working but I need a review of my code since I'm not proficient enough yet with rust to trigger a merge request as is. I have work on a separate branch of my personal fork. I also need to document and figure out some unit tests (not depending on Android device).

dcuddeback commented 9 years ago

@nibua-r For not being proficient at Rust, that looks pretty good! I think it's ready for a PR, but I'll leave some feedback here since I've already looked at your branch:

Thanks for spear-heading this feature. I'd be happy to help out in any way I can. Do you want help writing the documentation or tests?

r3n4ud commented 9 years ago

@dcuddeback Thank you for this constructive and comprehensive review!

I'll check this out and update my branch as soon as I can use some times on this.

r3n4ud commented 9 years ago

Tests are needed. Maybe some get_configuration using bare control_transfer should do?

BenoitZugmeyer commented 8 years ago

Btw, when it comes to control transfers, I think you're right that it should be implemented on the device handle, because they don't require claiming an interface first.

Are you sure about that? Disclaimer: I'm a beginner in both libusb and rust. I'm trying to adapt this script in rust, as an exercise (and because I want to see my mouse blinking)

In the script, they're are indeed claiming the interface before doing a control_transfer. I tried, without success, to do the same with libusb-rs, but whenever I run control_transfer function on the DeviceHandle, it fails, and the kernel logs:

usb 4-1.1: usbfs: process 23633 (test) did not claim interface 2 before use

I tried to move the control_transfer function to the InterfaceHandle, and it works like a charm.

EDIT: maybe you could add an example using control_transfer on on DeviceHandle?