# Path: trezorlib/transport/protocol.py
# class ProtocolBasedTransport(Transport):
#     """Transport that implements its communications through a Protocol.
# 
#     Intended as a base class for implementations that proxy their communication
#     operations to a Protocol.
#     """
# 
#     def __init__(self, protocol: Protocol) -> None:
#         self.protocol = protocol
# 
#     def write(self, message: protobuf.MessageType) -> None:
#         self.protocol.write(message)
# 
#     def read(self) -> protobuf.MessageType:
#         return self.protocol.read()
# 
#     def begin_session(self) -> None:
#         self.protocol.begin_session()
# 
#     def end_session(self) -> None:
#         self.protocol.end_session()
# 
# class ProtocolV1(Protocol):
#     """Protocol version 1. Currently (11/2018) in use on all Trezors.
#     Does not understand sessions.
#     """
# 
#     VERSION = 1
# 
#     def write(self, msg: protobuf.MessageType) -> None:
#         LOG.debug(
#             "sending message: {}".format(msg.__class__.__name__),
#             extra={"protobuf": msg},
#         )
#         data = BytesIO()
#         protobuf.dump_message(data, msg)
#         ser = data.getvalue()
#         header = struct.pack(">HL", mapping.get_type(msg), len(ser))
#         buffer = bytearray(b"##" + header + ser)
# 
#         while buffer:
#             # Report ID, data padded to 63 bytes
#             chunk = b"?" + buffer[: REPLEN - 1]
#             chunk = chunk.ljust(REPLEN, b"\x00")
#             self.handle.write_chunk(chunk)
#             buffer = buffer[63:]
# 
#     def read(self) -> protobuf.MessageType:
#         buffer = bytearray()
#         # Read header with first part of message data
#         msg_type, datalen, first_chunk = self.read_first()
#         buffer.extend(first_chunk)
# 
#         # Read the rest of the message
#         while len(buffer) < datalen:
#             buffer.extend(self.read_next())
# 
#         # Strip padding
#         data = BytesIO(buffer[:datalen])
# 
#         # Parse to protobuf
#         msg = protobuf.load_message(data, mapping.get_class(msg_type))
#         LOG.debug(
#             "received message: {}".format(msg.__class__.__name__),
#             extra={"protobuf": msg},
#         )
#         return msg
# 
#     def read_first(self) -> Tuple[int, int, bytes]:
#         chunk = self.handle.read_chunk()
#         if chunk[:3] != b"?##":
#             raise RuntimeError("Unexpected magic characters")
#         try:
#             headerlen = struct.calcsize(">HL")
#             msg_type, datalen = struct.unpack(">HL", chunk[3 : 3 + headerlen])
#         except Exception:
#             raise RuntimeError("Cannot parse header")
# 
#         data = chunk[3 + headerlen :]
#         return msg_type, datalen, data
# 
#     def read_next(self) -> bytes:
#         chunk = self.handle.read_chunk()
#         if chunk[:1] != b"?":
#             raise RuntimeError("Unexpected magic characters")
#         return chunk[1:]


import atexit
import logging
import sys
import time
    import usb1
from typing import Iterable, Optional
from . import TREZORS, UDEV_RULES_STR, TransportException
from .protocol import ProtocolBasedTransport, ProtocolV1
        while True:
            chunk = self.handle.interruptRead(endpoint, 64)
            if chunk:
                break
            else:
                time.sleep(0.001)
        if len(chunk) != 64:
            raise TransportException("Unexpected chunk size: %d" % len(chunk))
        return chunk


class WebUsbTransport(ProtocolBasedTransport):
    """
    WebUsbTransport implements transport over WebUSB interface.
    """

    PATH_PREFIX = "webusb"
    ENABLED = usb1 is not None
    context = None

    def __init__(
        self, device: str, handle: WebUsbHandle = None, debug: bool = False
    ) -> None:
        if handle is None:
            handle = WebUsbHandle(device, debug)

        self.device = device
        self.handle = handle
        self.debug = debug


# Path: trezorlib/transport/protocol.py
# class ProtocolBasedTransport(Transport):
#     """Transport that implements its communications through a Protocol.
# 
#     Intended as a base class for implementations that proxy their communication
#     operations to a Protocol.
#     """
# 
#     def __init__(self, protocol: Protocol) -> None:
#         self.protocol = protocol
# 
#     def write(self, message: protobuf.MessageType) -> None:
#         self.protocol.write(message)
# 
#     def read(self) -> protobuf.MessageType:
#         return self.protocol.read()
# 
#     def begin_session(self) -> None:
#         self.protocol.begin_session()
# 
#     def end_session(self) -> None:
#         self.protocol.end_session()
# 
# class ProtocolV1(Protocol):
#     """Protocol version 1. Currently (11/2018) in use on all Trezors.
#     Does not understand sessions.
#     """
# 
#     VERSION = 1
# 
#     def write(self, msg: protobuf.MessageType) -> None:
#         LOG.debug(
#             "sending message: {}".format(msg.__class__.__name__),
#             extra={"protobuf": msg},
#         )
#         data = BytesIO()
#         protobuf.dump_message(data, msg)
#         ser = data.getvalue()
#         header = struct.pack(">HL", mapping.get_type(msg), len(ser))
#         buffer = bytearray(b"##" + header + ser)
# 
#         while buffer:
#             # Report ID, data padded to 63 bytes
#             chunk = b"?" + buffer[: REPLEN - 1]
#             chunk = chunk.ljust(REPLEN, b"\x00")
#             self.handle.write_chunk(chunk)
#             buffer = buffer[63:]
# 
#     def read(self) -> protobuf.MessageType:
#         buffer = bytearray()
#         # Read header with first part of message data
#         msg_type, datalen, first_chunk = self.read_first()
#         buffer.extend(first_chunk)
# 
#         # Read the rest of the message
#         while len(buffer) < datalen:
#             buffer.extend(self.read_next())
# 
#         # Strip padding
#         data = BytesIO(buffer[:datalen])
# 
#         # Parse to protobuf
#         msg = protobuf.load_message(data, mapping.get_class(msg_type))
#         LOG.debug(
#             "received message: {}".format(msg.__class__.__name__),
#             extra={"protobuf": msg},
#         )
#         return msg
# 
#     def read_first(self) -> Tuple[int, int, bytes]:
#         chunk = self.handle.read_chunk()
#         if chunk[:3] != b"?##":
#             raise RuntimeError("Unexpected magic characters")
#         try:
#             headerlen = struct.calcsize(">HL")
#             msg_type, datalen = struct.unpack(">HL", chunk[3 : 3 + headerlen])
#         except Exception:
#             raise RuntimeError("Cannot parse header")
# 
#         data = chunk[3 + headerlen :]
#         return msg_type, datalen, data
# 
#     def read_next(self) -> bytes:
#         chunk = self.handle.read_chunk()
#         if chunk[:1] != b"?":
#             raise RuntimeError("Unexpected magic characters")
#         return chunk[1:]


# Path: trezorlib/transport/webusb.py
import atexit
import logging
import sys
import time
    import usb1
from typing import Iterable, Optional
from . import TREZORS, UDEV_RULES_STR, TransportException
from .protocol import ProtocolBasedTransport, ProtocolV1

        while True:
            chunk = self.handle.interruptRead(endpoint, 64)
            if chunk:
                break
            else:
                time.sleep(0.001)
        if len(chunk) != 64:
            raise TransportException("Unexpected chunk size: %d" % len(chunk))
        return chunk


class WebUsbTransport(ProtocolBasedTransport):
    """
    WebUsbTransport implements transport over WebUSB interface.
    """

    PATH_PREFIX = "webusb"
    ENABLED = usb1 is not None
    context = None

    def __init__(
        self, device: str, handle: WebUsbHandle = None, debug: bool = False
    ) -> None:
        if handle is None:
            handle = WebUsbHandle(device, debug)

        self.device = device
        self.handle = handle
        self.debug = debug


        super().__init__(protocol=ProtocolV1(handle))