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

Interrupt Transfers #77

Closed
MelbourneDeveloper opened this issue Jul 7, 2019 · 13 comments

Comments

@MelbourneDeveloper
Copy link
Owner

commented Jul 7, 2019

No description provided.

@MelbourneDeveloper

This comment has been minimized.

Copy link
Owner Author

commented Jul 7, 2019

@mxjones would I be right in saying that this article explains what interrupt transfers are about?

Can you just give me a rough rundown of how and why people need to use them?

Am I right in thinking that in the standard use case, you send data on the write endpoint, and receive on the read endpoint for normal control transfers? I.e. Usb.Net already works for Control Transfers, but doesn't work for interrupt transfers?

But, Interrupt transfers occur on a different endpoint altogether. The use case would be to continuously poll the interrupt endpoint right? So, it works just like the read endpoint, but is used for a different purpose?

@MelbourneDeveloper

This comment has been minimized.

Copy link
Owner Author

commented Jul 7, 2019

@mxjones should this be XferBulk? What about XferControl?

var isRead = usbEndpoint.Type == UsbAddressing.XferBulk && usbEndpoint.Direction != UsbAddressing.Out;

This was the original code. At least I was realistic about the chance of it working

//TODO: This is probably all wrong...
var isRead = usbEndpoint.Type == UsbAddressing.XferInterrupt && (int)usbEndpoint.Address == 129;
var isWrite = usbEndpoint.Type == UsbAddressing.XferInterrupt && ((int)usbEndpoint.Address == 1 || (int)usbEndpoint.Address == 2);
@MelbourneDeveloper

This comment has been minimized.

Copy link
Owner Author

commented Jul 7, 2019

@mxjones, I think I should point out that I don't know anything about USB. This whole set of libraries is literally just a port from a Java hardware wallet library that I just refactored until it worked on multiple platforms.

Shhh... Don't tell anyone.

@mxjones

This comment has been minimized.

Copy link

commented Jul 8, 2019

@MelbourneDeveloper

@mxjones would I be right in saying that this article explains what interrupt transfers are about?

Yes that article explains what they are about

Can you just give me a rough rundown of how and why people need to use them?

Sure, an example would be if a device has specific events that happen it can queue those up to let the host know - eg. Camera taking photos, on each photo an event is queued by the camera, host is polling for these events and can read them in - if it read that a photo was taken it can then respond to that.
I think Keyboards use this aswell, to push which keys have been pressed.

Am I right in thinking that in the standard use case, you send data on the write endpoint, and receive on the read endpoint for normal control transfers? I.e. Usb.Net already works for Control Transfers, but doesn't work for interrupt transfers?

I have not actually worked with Control transfers before, only Bulk & Interrupt - I think control transfers are for mostly configuring a device, or maybe small amounts of data. But yes I think you are correct that Usb.Net would already work for Control transfers - it also works for Bulk transfers (what I tested here) & Bulk Writes

But, Interrupt transfers occur on a different endpoint altogether. The use case would be to continuously poll the interrupt endpoint right? So, it works just like the read endpoint, but is used for a different purpose?

Correct, interrupt endpoints usually have a much smaller buffer size (8bytes) because it is used for transferring interrupt events mostly - the behaviour would be that you would poll ReadInterruptAsync continously, whilst nothing is queued on the device - this call will just 'hang' (this is why I added a timeout in my local & this issue related too #2) but as soon as an event is queued the call will return with that event information transmitted, yes it works just like the read endpoint (everything the same, except the endpoint will be interrupt)

@mxjones, I think I should point out that I don't know anything about USB. This whole set of libraries is literally just a port from a Java hardware wallet library that I just refactored until it worked on multiple platforms.

Shhh... Don't tell anyone.

Haha, I would say I am in a similiar boat - I worked with USB a bit in 2015 (on Android only) and again in 2017ish on Windows but not extensively - and now mostly was looking into possibilities of X-Platform USB comms all in .NET because, well it's cool :)

@mxjones

This comment has been minimized.

Copy link

commented Jul 8, 2019

@mxjones should this be XferBulk? What about XferControl?

Hmm, not sure about this - in my case it is XferBulk - but that could be specific to me...

var isRead = usbEndpoint.Type == UsbAddressing.XferBulk && usbEndpoint.Direction != UsbAddressing.Out;

This was the original code. At least I was realistic about the chance of it working

//TODO: This is probably all wrong...
var isRead = usbEndpoint.Type == UsbAddressing.XferInterrupt && (int)usbEndpoint.Address == 129;
var isWrite = usbEndpoint.Type == UsbAddressing.XferInterrupt && ((int)usbEndpoint.Address == 1 || (int)usbEndpoint.Address == 2);

Can you test if this gets the correct endpoints for your Trezor device aswell?

@MelbourneDeveloper

This comment has been minimized.

Copy link
Owner Author

commented Jul 8, 2019

@mxjones would it be worth polling the interrupt endpoint on behalf of the user, and raising an event when data is served up? I know that's how I'd want to consume interrupt data...

@MelbourneDeveloper

This comment has been minimized.

Copy link
Owner Author

commented Jul 8, 2019

@mxjones yes, I will test this soon. I will finish off refactoring before I do that though. I still have to do UWP which is going to be a bit difficult.

@mxjones

This comment has been minimized.

Copy link

commented Jul 9, 2019

@mxjones would it be worth polling the interrupt endpoint on behalf of the user, and raising an event when data is served up? I know that's how I'd want to consume interrupt data...

Yes, that is a good idea - would just need something so the user can signal that they want to poll the interrupt endpoint and then they can just hook up to the events

@MelbourneDeveloper

This comment has been minimized.

Copy link
Owner Author

commented Jul 16, 2019

@mxjones FYI: this is why interrupt endpoints are used in Usb.Net on Android and UWP: trezor/trezor-firmware#330

It was a mistake to base my design on the Trezor. Now, everything is being redesigned so as to work normally, but also be hackable for oddball devices like Trezor that use the interrupt channel.

Change in direction once again... Will keep you posted.

@MelbourneDeveloper

This comment has been minimized.

Copy link
Owner Author

commented Jul 16, 2019

@mxjones , I got this working on UWP, and the interrupt stuff still works.

public async Task<byte[]> ReadAsync()

Android will follow soon. Because I've had to take this detour, I think that interrupt transfers will be part of 3.0. I basically understand them now. They are essentially no different to other transfers, but they are meant to be used for events - not request/response style. There will be more infrastructure built around this in the long run. In the short term, I think it will be at least possible to use interrupt transfer.

@MelbourneDeveloper MelbourneDeveloper removed this from TODO in 3.1 Jul 17, 2019

@MelbourneDeveloper MelbourneDeveloper added this to Todo in 3.0 Jul 17, 2019

@mxjones

This comment has been minimized.

Copy link

commented Jul 17, 2019

@MelbourneDeveloper That sounds great! I haven't had a chance to look at the new code, or UWP stuff yet (next on my list to try out / test app!) but will have a look tomorrow at your new branch. I can also see where the confusion came from now, I hadn't actually dug into the Trezor code / sample apps so I didn't notice that - so good find!

@MelbourneDeveloper

This comment has been minimized.

Copy link
Owner Author

commented Jul 17, 2019

@mxjones maybe hold off for a bit. I'm still refactoring and cleaning up.

The good news is that the library will be way better off because of these changes. Interrupt transfers will be an inherent part of the system and all platforms will deal with setting interfaces and endpoints in the same way. The logic will not change from platform to platform.

It's been a crash course for me, but V3 is going to be the big one for USB.

@MelbourneDeveloper MelbourneDeveloper moved this from Todo to Done in 3.0 Jul 21, 2019

@MelbourneDeveloper

This comment has been minimized.

Copy link
Owner Author

commented Jul 21, 2019

@mxjones it should be possible to use the interrupt transfers if 3.0 beta. Please let me know if you have issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
2 participants
You can’t perform that action at this time.