forked from auracaster/bumble_mirror
fix after rebase merge
This commit is contained in:
@@ -495,6 +495,10 @@ async def run_assist(
|
||||
print(color('Scanning for any broadcast', 'cyan'))
|
||||
broadcast = await find_broadcast_by_name(device, broadcast_name)
|
||||
|
||||
if broadcast.broadcast_audio_announcement is None:
|
||||
print(color('No broadcast audio announcement found', 'red'))
|
||||
return
|
||||
|
||||
if (
|
||||
broadcast.basic_audio_announcement is None
|
||||
or not broadcast.basic_audio_announcement.subgroups
|
||||
|
||||
@@ -484,7 +484,7 @@ class Speaker:
|
||||
)
|
||||
) + bytes(bap.UnicastServerAdvertisingData())
|
||||
|
||||
def on_pdu(pdu: HCI_IsoDataPacket, ase: bap.AseStateMachine):
|
||||
def on_pdu(pdu: HCI_IsoDataPacket, ase: ascs.AseStateMachine):
|
||||
codec_config = ase.codec_specific_configuration
|
||||
assert isinstance(codec_config, bap.CodecSpecificConfiguration)
|
||||
pcm = decode(
|
||||
@@ -494,7 +494,7 @@ class Speaker:
|
||||
)
|
||||
self.device.abort_on('disconnection', self.ui_server.send_audio(pcm))
|
||||
|
||||
def on_ase_state_change(ase: bap.AseStateMachine) -> None:
|
||||
def on_ase_state_change(ase: ascs.AseStateMachine) -> None:
|
||||
if ase.state == ascs.AseStateMachine.State.STREAMING:
|
||||
codec_config = ase.codec_specific_configuration
|
||||
assert isinstance(codec_config, bap.CodecSpecificConfiguration)
|
||||
|
||||
@@ -988,7 +988,8 @@ class PeriodicAdvertisingSync(EventEmitter):
|
||||
self.device.periodic_advertising_syncs.remove(self)
|
||||
|
||||
async def transfer(self, connection: Connection, service_data: int = 0) -> None:
|
||||
await connection.transfer_periodic_sync(self.sync_handle, service_data)
|
||||
if self.sync_handle is not None:
|
||||
await connection.transfer_periodic_sync(self.sync_handle, service_data)
|
||||
|
||||
def on_establishment(
|
||||
self,
|
||||
@@ -3606,7 +3607,8 @@ class Device(CompositeEventEmitter):
|
||||
connection_handle=connection.handle,
|
||||
service_data=service_data,
|
||||
sync_handle=sync_handle,
|
||||
), check_result=True
|
||||
),
|
||||
check_result=True,
|
||||
)
|
||||
|
||||
async def find_peer_by_name(self, name, transport=BT_LE_TRANSPORT):
|
||||
@@ -3837,6 +3839,7 @@ class Device(CompositeEventEmitter):
|
||||
if self.keystore is None:
|
||||
raise InvalidOperationError('no key store')
|
||||
|
||||
logger.debug(f'Looking up key for {connection.peer_address}')
|
||||
keys = await self.keystore.get(str(connection.peer_address))
|
||||
if keys is None:
|
||||
raise InvalidOperationError('keys not found in key store')
|
||||
@@ -4315,6 +4318,12 @@ class Device(CompositeEventEmitter):
|
||||
role: int,
|
||||
connection_parameters: ConnectionParameters,
|
||||
) -> None:
|
||||
# Convert all-zeros addresses into None.
|
||||
if self_resolvable_address == Address.ANY_RANDOM:
|
||||
self_resolvable_address = None
|
||||
if peer_resolvable_address == Address.ANY_RANDOM:
|
||||
peer_resolvable_address = None
|
||||
|
||||
logger.debug(
|
||||
f'*** Connection: [0x{connection_handle:04X}] '
|
||||
f'{peer_address} {"" if role is None else HCI_Constant.role_name(role)}'
|
||||
@@ -4374,12 +4383,6 @@ class Device(CompositeEventEmitter):
|
||||
else self.random_address
|
||||
)
|
||||
|
||||
# Convert all-zeros addresses into None.
|
||||
if self_resolvable_address == Address.ANY_RANDOM:
|
||||
self_resolvable_address = None
|
||||
if peer_resolvable_address == Address.ANY_RANDOM:
|
||||
peer_resolvable_address = None
|
||||
|
||||
# Create a connection.
|
||||
connection = Connection(
|
||||
self,
|
||||
|
||||
@@ -24,6 +24,7 @@ from typing import Any, Dict, List, Optional, Sequence, Tuple, Type, Union
|
||||
|
||||
from bumble import colors
|
||||
from bumble.profiles.bap import CodecSpecificConfiguration
|
||||
from bumble.profiles import le_audio
|
||||
from bumble import device
|
||||
from bumble import gatt
|
||||
from bumble import gatt_client
|
||||
@@ -299,8 +300,7 @@ class AseStateMachine(gatt.Characteristic):
|
||||
presentation_delay = 0
|
||||
|
||||
# Additional parameters in ENABLING, STREAMING, DISABLING State
|
||||
# TODO: Parse this
|
||||
metadata = b''
|
||||
metadata = le_audio.Metadata()
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
@@ -447,7 +447,7 @@ class AseStateMachine(gatt.Characteristic):
|
||||
AseReasonCode.NONE,
|
||||
)
|
||||
|
||||
self.metadata = metadata
|
||||
self.metadata = le_audio.Metadata.from_bytes(metadata)
|
||||
self.state = self.State.ENABLING
|
||||
|
||||
return (AseResponseCode.SUCCESS, AseReasonCode.NONE)
|
||||
@@ -499,7 +499,7 @@ class AseStateMachine(gatt.Characteristic):
|
||||
AseResponseCode.INVALID_ASE_STATE_MACHINE_TRANSITION,
|
||||
AseReasonCode.NONE,
|
||||
)
|
||||
self.metadata = metadata
|
||||
self.metadata = le_audio.Metadata.from_bytes(metadata)
|
||||
return (AseResponseCode.SUCCESS, AseReasonCode.NONE)
|
||||
|
||||
def on_release(self) -> Tuple[AseResponseCode, AseReasonCode]:
|
||||
@@ -576,8 +576,9 @@ class AseStateMachine(gatt.Characteristic):
|
||||
self.State.STREAMING,
|
||||
self.State.DISABLING,
|
||||
):
|
||||
metadata_bytes = bytes(self.metadata)
|
||||
additional_parameters = (
|
||||
bytes([self.cig_id, self.cis_id, len(self.metadata)]) + self.metadata
|
||||
bytes([self.cig_id, self.cis_id, len(metadata_bytes)]) + metadata_bytes
|
||||
)
|
||||
else:
|
||||
additional_parameters = b''
|
||||
|
||||
@@ -23,6 +23,7 @@ import struct
|
||||
from typing import Optional, Sequence, Union
|
||||
|
||||
from bumble.profiles.bap import AudioLocation, CodecSpecificCapabilities, ContextType
|
||||
from bumble.profiles import le_audio
|
||||
from bumble import gatt
|
||||
from bumble import gatt_client
|
||||
from bumble import hci
|
||||
@@ -37,10 +38,11 @@ logger = logging.getLogger(__name__)
|
||||
# -----------------------------------------------------------------------------
|
||||
@dataclasses.dataclass
|
||||
class PacRecord:
|
||||
'''Published Audio Capabilities Service, Table 3.2/3.4.'''
|
||||
|
||||
coding_format: hci.CodingFormat
|
||||
codec_specific_capabilities: Union[CodecSpecificCapabilities, bytes]
|
||||
# TODO: Parse Metadata
|
||||
metadata: bytes = b''
|
||||
metadata: le_audio.Metadata = dataclasses.field(default_factory=le_audio.Metadata)
|
||||
|
||||
@classmethod
|
||||
def from_bytes(cls, data: bytes) -> PacRecord:
|
||||
@@ -53,7 +55,8 @@ class PacRecord:
|
||||
]
|
||||
offset += codec_specific_capabilities_size
|
||||
metadata_size = data[offset]
|
||||
metadata = data[offset : offset + metadata_size]
|
||||
offset += 1
|
||||
metadata = le_audio.Metadata.from_bytes(data[offset : offset + metadata_size])
|
||||
|
||||
codec_specific_capabilities: Union[CodecSpecificCapabilities, bytes]
|
||||
if coding_format.codec_id == hci.CodecID.VENDOR_SPECIFIC:
|
||||
@@ -71,12 +74,13 @@ class PacRecord:
|
||||
|
||||
def __bytes__(self) -> bytes:
|
||||
capabilities_bytes = bytes(self.codec_specific_capabilities)
|
||||
metadata_bytes = bytes(self.metadata)
|
||||
return (
|
||||
bytes(self.coding_format)
|
||||
+ bytes([len(capabilities_bytes)])
|
||||
+ capabilities_bytes
|
||||
+ bytes([len(self.metadata)])
|
||||
+ self.metadata
|
||||
+ bytes([len(metadata_bytes)])
|
||||
+ metadata_bytes
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -35,15 +35,13 @@ from bumble.hci import (
|
||||
CodingFormat,
|
||||
OwnAddressType,
|
||||
)
|
||||
from bumble.profiles.ascs import AudioStreamControlService
|
||||
from bumble.profiles.bap import (
|
||||
CodecSpecificCapabilities,
|
||||
ContextType,
|
||||
AudioLocation,
|
||||
SupportedSamplingFrequency,
|
||||
SupportedFrameDuration,
|
||||
PacRecord,
|
||||
PublishedAudioCapabilitiesService,
|
||||
AudioStreamControlService,
|
||||
UnicastServerAdvertisingData,
|
||||
)
|
||||
from bumble.profiles.mcp import (
|
||||
@@ -52,7 +50,7 @@ from bumble.profiles.mcp import (
|
||||
MediaState,
|
||||
MediaControlPointOpcode,
|
||||
)
|
||||
|
||||
from bumble.profiles.pacs import PacRecord, PublishedAudioCapabilitiesService
|
||||
from bumble.transport import open_transport_or_link
|
||||
|
||||
from typing import Optional
|
||||
|
||||
@@ -34,8 +34,8 @@ from bumble.hci import (
|
||||
CodingFormat,
|
||||
HCI_IsoDataPacket,
|
||||
)
|
||||
from bumble.profiles.ascs import AseStateMachine, AudioStreamControlService
|
||||
from bumble.profiles.bap import (
|
||||
AseStateMachine,
|
||||
UnicastServerAdvertisingData,
|
||||
CodecSpecificConfiguration,
|
||||
CodecSpecificCapabilities,
|
||||
@@ -43,13 +43,10 @@ from bumble.profiles.bap import (
|
||||
AudioLocation,
|
||||
SupportedSamplingFrequency,
|
||||
SupportedFrameDuration,
|
||||
PacRecord,
|
||||
PublishedAudioCapabilitiesService,
|
||||
AudioStreamControlService,
|
||||
)
|
||||
from bumble.profiles.cap import CommonAudioServiceService
|
||||
from bumble.profiles.csip import CoordinatedSetIdentificationService, SirkType
|
||||
|
||||
from bumble.profiles.pacs import PacRecord, PublishedAudioCapabilitiesService
|
||||
from bumble.transport import open_transport_or_link
|
||||
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ from bumble.hci import (
|
||||
CodingFormat,
|
||||
OwnAddressType,
|
||||
)
|
||||
from bumble.profiles.ascs import AudioStreamControlService
|
||||
from bumble.profiles.bap import (
|
||||
UnicastServerAdvertisingData,
|
||||
CodecSpecificCapabilities,
|
||||
@@ -37,10 +38,8 @@ from bumble.profiles.bap import (
|
||||
AudioLocation,
|
||||
SupportedSamplingFrequency,
|
||||
SupportedFrameDuration,
|
||||
PacRecord,
|
||||
PublishedAudioCapabilitiesService,
|
||||
AudioStreamControlService,
|
||||
)
|
||||
from bumble.profiles.pacs import PacRecord, PublishedAudioCapabilitiesService
|
||||
from bumble.profiles.cap import CommonAudioServiceService
|
||||
from bumble.profiles.csip import CoordinatedSetIdentificationService, SirkType
|
||||
from bumble.profiles.vcp import VolumeControlService
|
||||
|
||||
@@ -99,6 +99,7 @@ def test_operations() -> None:
|
||||
def basic_broadcast_receive_state_check(brs: bass.BroadcastReceiveState) -> None:
|
||||
serialized = bytes(brs)
|
||||
parsed = bass.BroadcastReceiveState.from_bytes(serialized)
|
||||
assert parsed is not None
|
||||
assert bytes(parsed) == serialized
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user