Coverage for src / bluetooth_sig / gatt / characteristics / sink_pac.py: 100%
20 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-03 16:41 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-03 16:41 +0000
1"""Sink PAC characteristic (0x2BC9)."""
3from __future__ import annotations
5import msgspec
7from ..context import CharacteristicContext
8from .base import BaseCharacteristic
9from .utils import DataParser
12class SinkPACData(msgspec.Struct, frozen=True, kw_only=True): # pylint: disable=too-few-public-methods
13 """Parsed data from Sink PAC characteristic.
15 Contains the number of PAC records and the raw record data.
16 Full PAC record parsing is complex (codec_id + capabilities + metadata)
17 and stored as raw bytes for downstream consumers.
18 """
20 number_of_pac_records: int
21 raw_data: bytes
24class SinkPACCharacteristic(BaseCharacteristic[SinkPACData]):
25 """Sink PAC characteristic (0x2BC9).
27 org.bluetooth.characteristic.sink_pac
29 Published Audio Capabilities for the sink role.
30 Contains codec capabilities for audio reception.
31 """
33 min_length = 1
34 allow_variable_length = True
36 def _decode_value(
37 self, data: bytearray, ctx: CharacteristicContext | None = None, *, validate: bool = True
38 ) -> SinkPACData:
39 """Parse Sink PAC data.
41 Format: number_of_pac_records (uint8) + variable PAC records.
42 """
43 record_count = DataParser.parse_int8(data, 0, signed=False)
44 raw_data = bytes(data[1:]) if len(data) > 1 else b""
45 return SinkPACData(
46 number_of_pac_records=record_count,
47 raw_data=raw_data,
48 )
50 def _encode_value(self, data: SinkPACData) -> bytearray:
51 """Encode Sink PAC data to bytes."""
52 result = bytearray()
53 result += DataParser.encode_int8(data.number_of_pac_records)
54 result += bytearray(data.raw_data)
55 return result