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

Get Report Size? #99

Open
vanweric opened this issue Jan 28, 2013 · 8 comments
Open

Get Report Size? #99

vanweric opened this issue Jan 28, 2013 · 8 comments

Comments

@vanweric
Copy link

My device works well on a USB2.0 port, but fails on 1.1. I believe that this is because 1.1 can only support up to 64 bytes per transaction, and I am attempting to send signficantly more than this.

I'd like to be able to report to the user that we do not support USB1.1 ports. How can I know whether or not I am on one?

@signal11
Copy link
Owner

That's a great question and I don't have the answer. I think more appropriately, you're interested in High Speed vs Full Speed.

@vanweric
Copy link
Author

Yes, you are correct. I conflated 1.1 vs 2.0 with High Speed vs Full Speed.

I believe that in Windows I can key off the the information within the HIDP_CAPS structure returned from HidP_GetCaps. This provides the sizes of the reports. In my specific use case, I would just fail out if it reports 64 bytes.

I do not know the mac or linux equivalents.

@signal11
Copy link
Owner

It's more complicated than that, and it needs to be done on the device side. You can have HID reports (interrupt transfers) longer than 64-bytes, but on full-speed connections you will need to send them as 64-byte transactions, the same as you'd do for a long bulk transaction (with a zero-length-packet at the end, if needed, per the USB spec).

It will take more than one frame to do this though. Interrupt endpoints only get one IN token per frame (and on Windows, it seems they get one every other frame). The HID code in windows, mac, and linux/hidraw will piece them together. The libusb HIDAPI implementation will not and you'll get each piece separately. This is a longstanding limitation (which can be worked around), which I'll get to one day (patches appreciated).

@vanweric
Copy link
Author

I am a bit confused. Are you saying that the device's firmware should be updated to support splitting messages over multiple transactions?

As a first step, I'd like to report input and output report lengths. Should this be done as an addition to the hid_device_info structure, or as new function call?

@signal11
Copy link
Owner

I am a bit confused. Are you saying that the device's firmware should be updated to support splitting messages over multiple transactions?

Yes, if you want it to support full-speed.

As a first step, I'd like to report input and output report lengths. Should this be done as an addition to the hid_device_info structure

That would be the place to put it. How do you plan to do that on other platforms? What really needs to happen is that the report descriptor needs to be parsed.

@vanweric
Copy link
Author

I have it working on Windows and Macintosh.

On Mac, your function get_int_property works:

cur_dev->input_report_length = get_int_property(dev, CFSTR(kIOHIDMaxInputReportSizeKey));
cur_dev->output_report_length = get_int_property(dev, CFSTR(kIOHIDMaxOutputReportSizeKey));
cur_dev->feature_report_length = get_int_property(dev, CFSTR(kIOHIDMaxFeatureReportSizeKey));

On Windows the caps structure already has this information filled out, with window's bonus byte included:

cur_dev->input_report_length =  caps.InputReportByteLength-1;
cur_dev->output_report_length = caps.OutputReportByteLength-1;
cur_dev->feature_report_length = caps.FeatureReportByteLength-1;

Would you like me to submit a patch for this? It may be easier to just drop these lines in to your hid.c files locally, and update hidapi.h to include the fields.

@signal11
Copy link
Owner

So you have your device working now with HS and FS? Did you end up having to return a different descriptor depending on the connection type?

On Linux the report descriptor will need to be parsed. This is something I've been wanting to do, but haven't gotten to yet.

@vanweric
Copy link
Author

Our device was never intended to work with FS - we wouldn't be able to fit a compelling user experience in to the limited bandwidth, and I would be startled if a computer exists that is FS only and able to run the rest of the software.

That said, it looks like it is working up to our protocol layer. I'd imagine that more flexible devices would handle it better. It is giving proper report lengths, and sending reports of the reported (reduced) size looks to go through just fine - until the device balks at the truncated packet.

TLDR; The generic / USB portions work... probably.

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

2 participants