diff --git a/apps/speaker/speaker.css b/apps/speaker/speaker.css index 075068b0c..dd4c79935 100644 --- a/apps/speaker/speaker.css +++ b/apps/speaker/speaker.css @@ -56,7 +56,7 @@ body, h1, h2, h3, h4, h5, h6 { border-radius: 4px; padding: 4px; margin: 6px; - margin-left: 0px; + margin-left: 0; } th, td { @@ -65,7 +65,7 @@ th, td { } .properties td:nth-child(even) { - background-color: #D6EEEE; + background-color: #d6eeee; font-family: monospace; } diff --git a/apps/speaker/speaker.html b/apps/speaker/speaker.html index f68abccb5..550049bc9 100644 --- a/apps/speaker/speaker.html +++ b/apps/speaker/speaker.html @@ -2,7 +2,7 @@ Bumble Speaker - + diff --git a/bumble/core.py b/bumble/core.py index 2e3f4af77..b00c40eea 100644 --- a/bumble/core.py +++ b/bumble/core.py @@ -78,7 +78,13 @@ def get_dict_key_by_value(dictionary, value): class BaseError(Exception): """Base class for errors with an error code, error name and namespace""" - def __init__(self, error_code, error_namespace='', error_name='', details=''): + def __init__( + self, + error_code: int | None, + error_namespace: str = '', + error_name: str = '', + details: str = '', + ): super().__init__() self.error_code = error_code self.error_namespace = error_namespace @@ -90,12 +96,14 @@ def __str__(self): namespace = f'{self.error_namespace}/' else: namespace = '' - if self.error_name: - name = f'{self.error_name} [0x{self.error_code:X}]' - else: - name = f'0x{self.error_code:X}' - - return f'{type(self).__name__}({namespace}{name})' + error_text = { + (True, True): f'{self.error_name} [0x{self.error_code:X}]', + (True, False): self.error_name, + (False, True): f'0x{self.error_code:X}', + (False, False): '', + }[(self.error_name != '', self.error_code is not None)] + + return f'{type(self).__name__}({namespace}{error_text})' class ProtocolError(BaseError): diff --git a/bumble/hfp.py b/bumble/hfp.py index 6d9e4282f..4b330751f 100644 --- a/bumble/hfp.py +++ b/bumble/hfp.py @@ -20,7 +20,7 @@ import dataclasses import enum import traceback -from typing import Dict, List, Union, Set +from typing import Dict, List, Union, Set, TYPE_CHECKING from . import at from . import rfcomm @@ -48,6 +48,15 @@ # ----------------------------------------------------------------------------- logger = logging.getLogger(__name__) +# ----------------------------------------------------------------------------- +# Error +# ----------------------------------------------------------------------------- + + +class HfpProtocolError(ProtocolError): + def __init__(self, error_name: str = '', details: str = ''): + super().__init__(None, 'hfp', error_name, details) + # ----------------------------------------------------------------------------- # Normative protocol definitions @@ -302,8 +311,12 @@ class HfProtocol: dlc: rfcomm.DLC command_lock: asyncio.Lock - response_queue: asyncio.Queue - unsolicited_queue: asyncio.Queue + if TYPE_CHECKING: + response_queue: asyncio.Queue[AtResponse] + unsolicited_queue: asyncio.Queue[AtResponse] + else: + response_queue: asyncio.Queue + unsolicited_queue: asyncio.Queue read_buffer: bytearray def __init__(self, dlc: rfcomm.DLC, configuration: Configuration): @@ -368,7 +381,7 @@ def _read_at(self, data: bytes): else: logger.warning(f"dropping unexpected response with code '{response.code}'") - # Send an AT command and wait for the peer resposne. + # Send an AT command and wait for the peer response. # Wait for the AT responses sent by the peer, to the status code. # Raises asyncio.TimeoutError if the status is not received # after a timeout (default 1 second). @@ -390,7 +403,7 @@ async def execute_command( ) if result.code == 'OK': if response_type == AtResponseType.SINGLE and len(responses) != 1: - raise ProtocolError("NO ANSWER") + raise HfpProtocolError("NO ANSWER") if response_type == AtResponseType.MULTIPLE: return responses @@ -398,7 +411,7 @@ async def execute_command( return responses[0] return None if result.code in STATUS_CODES: - raise ProtocolError(result.code) + raise HfpProtocolError(result.code) responses.append(result) # 4.2.1 Service Level Connection Initialization.