mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-18 04:18:10 +00:00
parent
aaa224a4f7
commit
8049282bdb
1
python/.changelog.d/1026.added
Normal file
1
python/.changelog.d/1026.added
Normal file
@ -0,0 +1 @@
|
||||
New exception type `DeviceIsBusy` indicates that the device is in use by another process.
|
1
python/.changelog.d/1026.fixed
Normal file
1
python/.changelog.d/1026.fixed
Normal file
@ -0,0 +1 @@
|
||||
trezorctl will correctly report that device is in use.
|
@ -21,9 +21,8 @@ from typing import TYPE_CHECKING, Any, Callable, Dict, Optional
|
||||
|
||||
import click
|
||||
|
||||
from .. import exceptions
|
||||
from .. import exceptions, transport
|
||||
from ..client import TrezorClient
|
||||
from ..transport import get_transport
|
||||
from ..ui import ClickUI, ScriptUI
|
||||
|
||||
if TYPE_CHECKING:
|
||||
@ -67,14 +66,14 @@ class TrezorConnection:
|
||||
def get_transport(self) -> "Transport":
|
||||
try:
|
||||
# look for transport without prefix search
|
||||
return get_transport(self.path, prefix_search=False)
|
||||
return transport.get_transport(self.path, prefix_search=False)
|
||||
except Exception:
|
||||
# most likely not found. try again below.
|
||||
pass
|
||||
|
||||
# look for transport with prefix search
|
||||
# if this fails, we want the exception to bubble up to the caller
|
||||
return get_transport(self.path, prefix_search=True)
|
||||
return transport.get_transport(self.path, prefix_search=True)
|
||||
|
||||
def get_ui(self) -> "TrezorClientUI":
|
||||
if self.script:
|
||||
@ -101,6 +100,9 @@ class TrezorConnection:
|
||||
"""
|
||||
try:
|
||||
client = self.get_client()
|
||||
except transport.DeviceIsBusy:
|
||||
click.echo("Device is in use by another process.")
|
||||
sys.exit(1)
|
||||
except Exception:
|
||||
click.echo("Failed to find a Trezor device.")
|
||||
if self.path is not None:
|
||||
|
@ -26,7 +26,7 @@ import click
|
||||
|
||||
from .. import log, messages, protobuf, ui
|
||||
from ..client import TrezorClient
|
||||
from ..transport import enumerate_devices
|
||||
from ..transport import DeviceIsBusy, enumerate_devices
|
||||
from ..transport.udp import UdpTransport
|
||||
from . import (
|
||||
AliasedGroup,
|
||||
@ -247,9 +247,15 @@ def list_devices(no_resolve: bool) -> Optional[Iterable["Transport"]]:
|
||||
return enumerate_devices()
|
||||
|
||||
for transport in enumerate_devices():
|
||||
try:
|
||||
client = TrezorClient(transport, ui=ui.ClickUI())
|
||||
click.echo(f"{transport} - {format_device_name(client.features)}")
|
||||
description = format_device_name(client.features)
|
||||
client.end_session()
|
||||
except DeviceIsBusy:
|
||||
description = "Device is in use by another process"
|
||||
except Exception:
|
||||
description = "Failed to read details"
|
||||
click.echo(f"{transport} - {description}")
|
||||
return None
|
||||
|
||||
|
||||
|
@ -48,6 +48,10 @@ class TransportException(TrezorException):
|
||||
pass
|
||||
|
||||
|
||||
class DeviceIsBusy(TransportException):
|
||||
pass
|
||||
|
||||
|
||||
class Transport:
|
||||
"""Raw connection to a Trezor device.
|
||||
|
||||
|
@ -21,7 +21,7 @@ from typing import TYPE_CHECKING, Any, Dict, Iterable, Optional
|
||||
import requests
|
||||
|
||||
from ..log import DUMP_PACKETS
|
||||
from . import MessagePayload, Transport, TransportException
|
||||
from . import DeviceIsBusy, MessagePayload, Transport, TransportException
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from ..models import TrezorModel
|
||||
@ -37,14 +37,19 @@ CONNECTION = requests.Session()
|
||||
CONNECTION.headers.update(TREZORD_ORIGIN_HEADER)
|
||||
|
||||
|
||||
def call_bridge(uri: str, data: Optional[str] = None) -> requests.Response:
|
||||
url = TREZORD_HOST + "/" + uri
|
||||
class BridgeException(TransportException):
|
||||
def __init__(self, path: str, status: int, message: str) -> None:
|
||||
self.path = path
|
||||
self.status = status
|
||||
self.message = message
|
||||
super().__init__(f"trezord: {path} failed with code {status}: {message}")
|
||||
|
||||
|
||||
def call_bridge(path: str, data: Optional[str] = None) -> requests.Response:
|
||||
url = TREZORD_HOST + "/" + path
|
||||
r = CONNECTION.post(url, data=data)
|
||||
if r.status_code != 200:
|
||||
error_str = (
|
||||
f"trezord: {uri} failed with code {r.status_code}: {r.json()['error']}"
|
||||
)
|
||||
raise TransportException(error_str)
|
||||
raise BridgeException(path, r.status_code, r.json()["error"])
|
||||
return r
|
||||
|
||||
|
||||
@ -150,7 +155,12 @@ class BridgeTransport(Transport):
|
||||
return []
|
||||
|
||||
def begin_session(self) -> None:
|
||||
try:
|
||||
data = self._call("acquire/" + self.device["path"])
|
||||
except BridgeException as e:
|
||||
if e.message == "wrong previous session":
|
||||
raise DeviceIsBusy(self.device["path"]) from e
|
||||
raise
|
||||
self.session = data.json()["session"]
|
||||
|
||||
def end_session(self) -> None:
|
||||
|
@ -22,7 +22,7 @@ from typing import Iterable, List, Optional
|
||||
|
||||
from ..log import DUMP_PACKETS
|
||||
from ..models import TREZORS, TrezorModel
|
||||
from . import UDEV_RULES_STR, TransportException
|
||||
from . import UDEV_RULES_STR, DeviceIsBusy, TransportException
|
||||
from .protocol import ProtocolBasedTransport, ProtocolV1
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
@ -57,7 +57,10 @@ class WebUsbHandle:
|
||||
else:
|
||||
args = ()
|
||||
raise IOError("Cannot open device", *args)
|
||||
try:
|
||||
self.handle.claimInterface(self.interface)
|
||||
except usb1.USBErrorAccess as e:
|
||||
raise DeviceIsBusy(self.device) from e
|
||||
|
||||
def close(self) -> None:
|
||||
if self.handle is not None:
|
||||
|
Loading…
Reference in New Issue
Block a user