From 460e88ee536494d9cf9c66b4993d91ea4eccff8a Mon Sep 17 00:00:00 2001 From: slush Date: Tue, 6 Feb 2018 19:11:14 +0100 Subject: [PATCH] hw plugins: Allow custom enumerate functions trezor: Adding support for all supported transports (HID, WebUSB, UDP, Bridge) --- lib/plugins.py | 10 ++++++++++ plugins/trezor/plugin.py | 26 +++++--------------------- plugins/trezor/trezor.py | 17 +++++++++-------- 3 files changed, 24 insertions(+), 29 deletions(-) diff --git a/lib/plugins.py b/lib/plugins.py index e94013a2..b3611c16 100644 --- a/lib/plugins.py +++ b/lib/plugins.py @@ -312,6 +312,8 @@ class DeviceMgr(ThreadJob, PrintError): # What we recognise. Each entry is a (vendor_id, product_id) # pair. self.recognised_hardware = set() + # Custom enumerate functions for devices we don't know about. + self.enumerate_func = set() # For synchronization self.lock = threading.RLock() self.hid_lock = threading.RLock() @@ -334,6 +336,9 @@ class DeviceMgr(ThreadJob, PrintError): for pair in device_pairs: self.recognised_hardware.add(pair) + def register_enumerate_func(self, func): + self.enumerate_func.add(func) + def create_client(self, device, handler, plugin): # Get from cache first client = self.client_lookup(device.id_) @@ -509,6 +514,7 @@ class DeviceMgr(ThreadJob, PrintError): self.print_error("scanning devices...") with self.hid_lock: hid_list = hid.enumerate(0, 0) + # First see what's connected that we know about devices = [] for d in hid_list: @@ -524,6 +530,10 @@ class DeviceMgr(ThreadJob, PrintError): devices.append(Device(d['path'], interface_number, id_, product_key, usage_page)) + # Let plugin handlers enumerate devices we don't know about + for f in self.enumerate_func: + devices.extend(f()) + # Now find out what was disconnected pairs = [(dev.path, dev.id_) for dev in devices] disconnected_ids = [] diff --git a/plugins/trezor/plugin.py b/plugins/trezor/plugin.py index 15fdb752..d828f8ae 100644 --- a/plugins/trezor/plugin.py +++ b/plugins/trezor/plugin.py @@ -84,38 +84,22 @@ class TrezorCompatiblePlugin(HW_PluginBase): def __init__(self, parent, config, name): HW_PluginBase.__init__(self, parent, config, name) self.main_thread = threading.current_thread() - # FIXME: move to base class when Ledger is fixed if self.libraries_available: - self.device_manager().register_devices(self.DEVICE_IDS) + self.device_manager().register_enumerate_func(self.enumerate) - def _try_hid(self, device): - self.print_error("Trying to connect over USB...") + def create_client(self, device, handler): try: - return self.hid_transport(device) + self.print_error("Trying to connect to TREZOR...") + transport = self.transport(device) except BaseException as e: - # see fdb810ba622dc7dbe1259cbafb5b28e19d2ab114 - # raise self.print_error("cannot connect at", device.path, str(e)) return None - def _try_bridge(self, device): - self.print_error("Trying to connect over Trezor Bridge...") - try: - return self.bridge_transport({'path': hexlify(device.path)}) - except BaseException as e: - self.print_error("cannot connect to bridge", str(e)) - return None - - def create_client(self, device, handler): - # disable bridge because it seems to never returns if keepkey is plugged - #transport = self._try_bridge(device) or self._try_hid(device) - transport = self._try_hid(device) if not transport: - self.print_error("cannot connect to device") + self.print_error("cannot connect at", device.path) return self.print_error("connected to device at", device.path) - client = self.client_class(transport, handler, self) # Try a ping for device sanity diff --git a/plugins/trezor/trezor.py b/plugins/trezor/trezor.py index 5ee31d39..258275db 100644 --- a/plugins/trezor/trezor.py +++ b/plugins/trezor/trezor.py @@ -16,21 +16,22 @@ class TrezorPlugin(TrezorCompatiblePlugin): from . import client import trezorlib import trezorlib.ckd_public - import trezorlib.transport_hid import trezorlib.messages + import trezorlib.device self.client_class = client.TrezorClient self.ckd_public = trezorlib.ckd_public self.types = trezorlib.messages - self.DEVICE_IDS = (trezorlib.transport_hid.DEV_TREZOR1, trezorlib.transport_hid.DEV_TREZOR2) + self.DEVICE_IDS = ('TREZOR',) self.libraries_available = True except ImportError: self.libraries_available = False TrezorCompatiblePlugin.__init__(self, *args) - def hid_transport(self, device): - from trezorlib.transport_hid import HidTransport - return HidTransport.find_by_path(device.path) + def enumerate(self): + from trezorlib.device import TrezorDevice + from electrum.plugins import Device + return [Device(str(d), -1, str(d), 'TREZOR', 0) for d in TrezorDevice.enumerate()] - def bridge_transport(self, d): - from trezorlib.transport_bridge import BridgeTransport - return BridgeTransport(d) + def transport(self, device): + from trezorlib.device import TrezorDevice + return TrezorDevice.find_by_path(device.path)