diff --git a/bumble/transport/common.py b/bumble/transport/common.py index 60286b2..b00bf7e 100644 --- a/bumble/transport/common.py +++ b/bumble/transport/common.py @@ -248,26 +248,26 @@ class AsyncPipeSink: # ----------------------------------------------------------------------------- -class ParserSource: +class BaseSource: """ Base class designed to be subclassed by transport-specific source classes """ terminated: asyncio.Future[None] - parser: PacketParser + sink: Optional[TransportSink] def __init__(self) -> None: - self.parser = PacketParser() self.terminated = asyncio.get_running_loop().create_future() + self.sink = None def set_packet_sink(self, sink: TransportSink) -> None: - self.parser.set_packet_sink(sink) + self.sink = sink def on_transport_lost(self) -> None: self.terminated.set_result(None) - if self.parser.sink: - if hasattr(self.parser.sink, 'on_transport_lost'): - self.parser.sink.on_transport_lost() + if self.sink: + if hasattr(self.sink, 'on_transport_lost'): + self.sink.on_transport_lost() async def wait_for_termination(self) -> None: """ @@ -280,6 +280,23 @@ class ParserSource: pass +# ----------------------------------------------------------------------------- +class ParserSource(BaseSource): + """ + Base class for sources that use an HCI parser. + """ + + parser: PacketParser + + def __init__(self) -> None: + super().__init__() + self.parser = PacketParser() + + def set_packet_sink(self, sink: TransportSink) -> None: + super().set_packet_sink(sink) + self.parser.set_packet_sink(sink) + + # ----------------------------------------------------------------------------- class StreamPacketSource(asyncio.Protocol, ParserSource): def data_received(self, data: bytes) -> None: diff --git a/bumble/transport/usb.py b/bumble/transport/usb.py index 2067ec6..2e98446 100644 --- a/bumble/transport/usb.py +++ b/bumble/transport/usb.py @@ -24,7 +24,7 @@ import platform import usb1 -from bumble.transport.common import Transport, ParserSource, TransportInitError +from bumble.transport.common import Transport, BaseSource, TransportInitError from bumble import hci from bumble.colors import color @@ -208,7 +208,7 @@ async def open_usb_transport(spec: str) -> Transport: except usb1.USBError: logger.debug('OUT transfer likely already completed') - class UsbPacketSource(asyncio.Protocol, ParserSource): + class UsbPacketSource(asyncio.Protocol, BaseSource): def __init__(self, device, metadata, acl_in, events_in): super().__init__() self.device = device @@ -285,7 +285,13 @@ async def open_usb_transport(spec: str) -> Transport: packet = await self.queue.get() except asyncio.CancelledError: return - self.parser.feed_data(packet) + if self.sink: + try: + self.sink.on_packet(packet) + except Exception as error: + logger.exception( + color(f'!!! Exception in sink.on_packet: {error}', 'red') + ) def close(self): self.closed = True