Author Topic: How to get full feature report when your buffer is shorter than data size on USB  (Read 14676 times)

Galloden

  • Member
  • ***
  • Posts: 3
I am developing a small application. In this application I need to read the data from a USB device. (Card swipe). I can read the swipe event data just fine. However I am having trouble understanding getting the feature data.

The FeatureReportSize on my device is 9, this comes from the HID descriptors

I use HidD_SetFeature with the appropriate bytes to tell the device to prepare the data buffer with the data I want to read. I am not changing any feature data here, just getting it into the data buffer of the device.

I then call HidD_GetFeature with the appropriate ReportID that I gave SetFeature and I get back a byte[9] array back populated with data. But heres the problem, my feature that I am trying to read is 40 bytes long. So my I only get the first small fraction of the actual data.

I did find that if I keep calling HidD_GetFeature over and over again it will give me more data of the buffer back, her's were my questions come in.

Is this the correct way to go about getting feature data that is greater than the buffer size, to spam HidD_GetFeature until you get all your data out of it? If the data is variable size, how would I know how many times to call HidD_GetFeature? Should I be looping HidD_GetFeature to get this data?

Also after I call HidD_SetFeature, I immediately call HidD_GetFeature and my buffer will be populated, however if wait 1 second and then call HidD_GetFeature then I get nothing. All 0's back. Nothing is different except that 1 second delay. Why is this? Is there some sort of window I must go and get this data? I have looked all over the internet for the answers to these questions but cant find anything.

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
HID reports are a fixed size, defined in the report descriptor. If the report size is 40 bytes, the device should be programmed to send a complete 40-byte report in response to a request for the Feature report. Depending on the MaxPacketSize for endpoint zero, sending the report might require multiple transactions in the Data stage of the transfer. The device firmware needs to be programmed to handle that.

If the report size varies, the report descriptor should define multiple reports, each with a different report ID. If you want to use a single report ID, the device will need to pad shorter reports to match the length in the report descriptor.


Galloden

  • Member
  • ***
  • Posts: 3
Thanks for replying Jan.

I might have used some wrong terminology  in my post? The report buffer is 9, but this same buffer is used to get data much larger than 9 bytes. So I have to keep querying Get_Report (using HidD_SetFeature in hid.dll)

Please view this image here ( I just uploaded it) http://i.imgur.com/Vt6443A.png

Attached is an image of a USB sniffer. There is duplication for every transfer due to the sniffer but the commands can still be seen. This was captured using the configuration application that came with the device byt getting the settings of the device. As you can see when I requested the settings of the device, it commanded a Set Report to the device. (Very first log in the grid in my screenshot). Then, every subsequent transfer is a Get Report(Feature len:8), for a total of 16 Get Report commands in a row, each carrying a data array that is a continuation of the previous one until it gets to the last one then it gives the last report and the LRC.

From what you said is that they should resize the report size to fit all of this data into a single report? From the looks of this USB sniffer and using the ID Tech configuration application (no source =\) , it looks like they send a hidD_SetFeature, followed by 16 hidD_GetFeatures in succession.

Now, I am trying to do this same thing in my application. Problem is, the number of reports I have to go out and fetch are variable( for this one in the screenshot was 16, some are 12, some are 2, some are 1, some are N). So I am trying to determine how many times I need to fire off Get_Report to get all the data, and if this is even the way to go about doing this.

My other question is maybe a timeout issue? Refering to my screen shot again, you can see that there is a 1 second delay from Set_Report and the first Get_Report. If that delay goes from 1 second to 2 seconds so the flow would be
Set_Report
Wait 2 second
Get_Report

Now get report will have nothing in the response, all 0's. Does anyone know why this is? Is there a timeout or some sort going on in getting feature data?

Thank you Jan and all very much for your attention!

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
The report descriptor in the capture defines the Feature report as 8 bytes.

(On the host, the HidD_GetFeature and HidDSetFeature buffers require an additional, initial byte for the report ID.)

If you want to send and receive more than 8 bytes, you can:

Use the current report descriptor and transfer multiple reports, each containing a portion of the data the host or device wants to send.

or

Edit the report descriptor to define a larger report. Pad the report as needed if you have less data to send.

or

Define multiple reports, each with a different report ID and different report size.

When you delay in requesting a report, it looks like the device firmware has overwritten the buffer where the report data is stored.





Galloden

  • Member
  • ***
  • Posts: 3
Thanks for replying again Jan, the information you provide is great.

So this is a pretty normal practice then? To request the report via several Get_Report transfer? (For instance in this case hidDSet_Feature followed by several immediate hidDGet_Feature commands directly following each other)?

I ask because this kind of scenario is not present in any documentation or examples or books I can find. Its usually just one hidDSet_Feature followed by one hidDGet_Feature and it is assumed that all the data is in the single hidDGet_Feature report. Nowhere do I find examples or articles explaining how to get the data if it requires multiple hidDGet_Feature commands for the same data packet.

I don't want to alter the report descriptors on the device.So what I suppose I will implement in my application is to send off the single hidDSet_Feature command so the device will get the data in its data buffer, then after that just keep looping hidDGet_Feature until I clear it out. That sound about right? I just want to make sure I'm going about this right. Sorry if this seems repetitive.

Again, thank you so much for your help. I just ordered your book off Amazon.

Jan Axelson

  • Administrator
  • Frequent Contributor
  • *****
  • Posts: 3033
    • Lakeview Research
No, it is not normal practice. But if you don't want to change the report descriptor yet you want to retrieve more data than will fit in a single report, you will need to request multiple reports, each containing a portion of the data.