forked from auracaster/bumble_mirror
Merge pull request #783 from zxzxwu/avrcp
AVCTP: Change callback packet type to bytes
This commit is contained in:
@@ -19,10 +19,11 @@ from __future__ import annotations
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
import struct
|
import struct
|
||||||
|
from collections.abc import Callable
|
||||||
from enum import IntEnum
|
from enum import IntEnum
|
||||||
from typing import Callable, Optional, cast
|
from typing import Optional
|
||||||
|
|
||||||
from bumble import avc, core, l2cap
|
from bumble import core, l2cap
|
||||||
from bumble.colors import color
|
from bumble.colors import color
|
||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
@@ -144,9 +145,9 @@ class MessageAssembler:
|
|||||||
|
|
||||||
# -----------------------------------------------------------------------------
|
# -----------------------------------------------------------------------------
|
||||||
class Protocol:
|
class Protocol:
|
||||||
CommandHandler = Callable[[int, avc.CommandFrame], None]
|
CommandHandler = Callable[[int, bytes], None]
|
||||||
command_handlers: dict[int, CommandHandler] # Command handlers, by PID
|
command_handlers: dict[int, CommandHandler] # Command handlers, by PID
|
||||||
ResponseHandler = Callable[[int, Optional[avc.ResponseFrame]], None]
|
ResponseHandler = Callable[[int, Optional[bytes]], None]
|
||||||
response_handlers: dict[int, ResponseHandler] # Response handlers, by PID
|
response_handlers: dict[int, ResponseHandler] # Response handlers, by PID
|
||||||
next_transaction_label: int
|
next_transaction_label: int
|
||||||
message_assembler: MessageAssembler
|
message_assembler: MessageAssembler
|
||||||
@@ -204,20 +205,15 @@ class Protocol:
|
|||||||
self.send_ipid(transaction_label, pid)
|
self.send_ipid(transaction_label, pid)
|
||||||
return
|
return
|
||||||
|
|
||||||
command_frame = cast(avc.CommandFrame, avc.Frame.from_bytes(payload))
|
self.command_handlers[pid](transaction_label, payload)
|
||||||
self.command_handlers[pid](transaction_label, command_frame)
|
|
||||||
else:
|
else:
|
||||||
if pid not in self.response_handlers:
|
if pid not in self.response_handlers:
|
||||||
logger.warning(f"no response handler for PID {pid}")
|
logger.warning(f"no response handler for PID {pid}")
|
||||||
return
|
return
|
||||||
|
|
||||||
# By convention, for an ipid, send a None payload to the response handler.
|
# By convention, for an ipid, send a None payload to the response handler.
|
||||||
if ipid:
|
response_payload = None if ipid else payload
|
||||||
response_frame = None
|
self.response_handlers[pid](transaction_label, response_payload)
|
||||||
else:
|
|
||||||
response_frame = cast(avc.ResponseFrame, avc.Frame.from_bytes(payload))
|
|
||||||
|
|
||||||
self.response_handlers[pid](transaction_label, response_frame)
|
|
||||||
|
|
||||||
def send_message(
|
def send_message(
|
||||||
self,
|
self,
|
||||||
|
|||||||
@@ -22,21 +22,9 @@ import enum
|
|||||||
import functools
|
import functools
|
||||||
import logging
|
import logging
|
||||||
import struct
|
import struct
|
||||||
|
from collections.abc import AsyncIterator, Awaitable, Callable, Iterable, Sequence
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from typing import (
|
from typing import ClassVar, Optional, SupportsBytes, TypeVar, Union
|
||||||
AsyncIterator,
|
|
||||||
Awaitable,
|
|
||||||
Callable,
|
|
||||||
ClassVar,
|
|
||||||
Iterable,
|
|
||||||
List,
|
|
||||||
Optional,
|
|
||||||
Sequence,
|
|
||||||
SupportsBytes,
|
|
||||||
TypeVar,
|
|
||||||
Union,
|
|
||||||
cast,
|
|
||||||
)
|
|
||||||
|
|
||||||
from bumble import avc, avctp, core, hci, l2cap, utils
|
from bumble import avc, avctp, core, hci, l2cap, utils
|
||||||
from bumble.colors import color
|
from bumble.colors import color
|
||||||
@@ -1762,7 +1750,11 @@ class Protocol(utils.EventEmitter):
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
response = self._check_response(response_context, GetCapabilitiesResponse)
|
response = self._check_response(response_context, GetCapabilitiesResponse)
|
||||||
return cast(List[EventId], response.capabilities)
|
return list(
|
||||||
|
capability
|
||||||
|
for capability in response.capabilities
|
||||||
|
if isinstance(capability, EventId)
|
||||||
|
)
|
||||||
|
|
||||||
async def get_play_status(self) -> SongAndPlayStatus:
|
async def get_play_status(self) -> SongAndPlayStatus:
|
||||||
"""Get the play status of the connected peer."""
|
"""Get the play status of the connected peer."""
|
||||||
@@ -2012,9 +2004,12 @@ class Protocol(utils.EventEmitter):
|
|||||||
|
|
||||||
self.emit(self.EVENT_STOP)
|
self.emit(self.EVENT_STOP)
|
||||||
|
|
||||||
def _on_avctp_command(
|
def _on_avctp_command(self, transaction_label: int, payload: bytes) -> None:
|
||||||
self, transaction_label: int, command: avc.CommandFrame
|
command = avc.CommandFrame.from_bytes(payload)
|
||||||
) -> None:
|
if not isinstance(command, avc.CommandFrame):
|
||||||
|
raise core.InvalidPacketError(
|
||||||
|
f"{command} is not a valid AV/C Command Frame"
|
||||||
|
)
|
||||||
logger.debug(
|
logger.debug(
|
||||||
f"<<< AVCTP Command, transaction_label={transaction_label}: " f"{command}"
|
f"<<< AVCTP Command, transaction_label={transaction_label}: " f"{command}"
|
||||||
)
|
)
|
||||||
@@ -2073,8 +2068,13 @@ class Protocol(utils.EventEmitter):
|
|||||||
self.send_not_implemented_response(transaction_label, command)
|
self.send_not_implemented_response(transaction_label, command)
|
||||||
|
|
||||||
def _on_avctp_response(
|
def _on_avctp_response(
|
||||||
self, transaction_label: int, response: Optional[avc.ResponseFrame]
|
self, transaction_label: int, payload: Optional[bytes]
|
||||||
) -> None:
|
) -> None:
|
||||||
|
response = avc.ResponseFrame.from_bytes(payload) if payload else None
|
||||||
|
if not isinstance(response, avc.ResponseFrame):
|
||||||
|
raise core.InvalidPacketError(
|
||||||
|
f"{response} is not a valid AV/C Response Frame"
|
||||||
|
)
|
||||||
logger.debug(
|
logger.debug(
|
||||||
f"<<< AVCTP Response, transaction_label={transaction_label}: {response}"
|
f"<<< AVCTP Response, transaction_label={transaction_label}: {response}"
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user