gary-rowe / hid4java

A cross-platform Java Native Access (JNA) wrapper for the libusb/hidapi library. Works out of the box on Windows/Mac/Linux.
MIT License
229 stars 71 forks source link

Trezor device USB attach takes long time on Windows #42

Closed martin-lizner closed 4 years ago

martin-lizner commented 8 years ago

The problem is that after providing the PIN to Trezor (bitcoin hw wallet), doing software detach in HID Java API and starting the API again, USB init takes about 30 seconds to complete. The only cure is to do hard USB detach (unplug cable :-)

Repeat scenario is described here: keepkey/multibit-hardware#29

The trezor guys point to hid level issues, at least I think they do. Details here: https://github.com/trezor/trezor-mcu/issues/98

Thanks, M.

jhoenicke commented 8 years ago

Le me explain what goes wrong (at least under Linux):

The PC sends "GET DESCRIPTOR STRING" every 0.5s, probably due to reenumerating the usb devices. This is a problem when Trezor is busy (e.g. computing the master seed). In that case it cannot answer the request in time. Unfortunately, when it replies later, the USB stack doesn't recover from this problem.

gary-rowe commented 8 years ago

I've been away for a bit and didn't see this until recently. Many thanks to @jhoenicke for doing the investigation to uncover the problem.

I've pushed a quick workaround to allow a simple way to increase the scan interval so that it doesn't hammer constrained devices so much. I'll see about improving the resiliency of the stack under these circumstances.

gary-rowe commented 8 years ago

Just as a general update, exposing the scan interval so it can be reduced is not sufficient to fix the problem with the device showing the problem. I'm planning to introduce a collection of scanning modes to allow much more flexibility when dealing with constrained devices. All being well a first draft of this approach will be available later today.

martin-lizner commented 8 years ago

Hi, with latest hid4java master Im not even able to get my trezor device (both 1.3.5 and 1.3.6 fw) to ready state. And it does not matter what I set in HidManager.getHidServices.

1.3.6 fw just shows CONNECTED state and waits 1.3.5 returns ERROR o.m.h.h.t.w.v.TrezorV1HidHardwareWallet - Unknown HID version.

gary-rowe commented 8 years ago

@martin-lizner Have you tried the latest develop branch? There's quite a few modifications going in for 0.5.0. I have a couple of hours left today so I'll try to get something workable in place for you asap.

martin-lizner commented 8 years ago

oops, sorry... talking about develop branch... so yes, latest

0.4.0 works ok with MB HW with our without this PR (support for 1.3.6 Trezor fw)

gary-rowe commented 8 years ago

Thanks, @martin-lizner. I've pushed support for different scan modes on the develop branch. To use them you'll need to first verify they work for you with the UsbHidDeviceExample in hid4java. This should just do some low level attach/detach/Trezor initialise messages.

What will be interesting will be the delay after write of 5000ms before scanning resumes. You may want to hand craft some more complex messages to verify that the USB stack isn't getting corrupted now. Unfortunately, I've run out of time for testing across platforms until tomorrow at best.

If you want to plumb this into MBHW and give it a whirl (completely untested) you'll need to use the new HidSpecification method signature in HidServices:

    // Configure to use custom specification
    HidServicesSpecification hidServicesSpecification = new HidServicesSpecification();
    hidServicesSpecification.setAutoShutdown(true);
    hidServicesSpecification.setScanInterval(500);
    hidServicesSpecification.setPauseInterval(5000);
    hidServicesSpecification.setScanMode(ScanMode.SCAN_AT_FIXED_INTERVAL_WITH_PAUSE_AFTER_WRITE);

    // Get HID services using custom specification
    HidServices hidServices = HidManager.getHidServices(hidServicesSpecification);
    hidServices.addHidServicesListener(this);

    // Start the services
    hidServices.start();

Let me know how you get on.

martin-lizner commented 8 years ago

Thanks Gary, I confirm I can enumerate Trezor 1.3.5 on USB via this example. But Im unable to validate whether it helped to the problem (attach slowness) since Im strugling in integrating this into MBHW.

The thing is that in MBHW I can only see device as CONNECTED, but it never gets to READY state. I even tried "vanilla" MBHW without support for newer firmware - same. Switching back na 0.4.0 hid4java resolves the problem immediatelly. So there is smth that was introduced between 0.4.0 tag and 0.5.0 (devel) which obstructs Trezor from going to READY state...

jhoenicke commented 8 years ago

@martin-lizner Which OS are you using? I suspect it may be related to #43.

martin-lizner commented 8 years ago

@jhoenicke Windows 10, but - if hack was also in 0.4.0 - all is fine with 0.4.0 on my OS

gary-rowe commented 4 years ago

I think this is resolved, so I'll close this issue.