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.