Coverage for src / bluetooth_sig / gatt / characteristics / sink_ase.py: 100%
33 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 ASE characteristic (0x2BC4)."""
3from __future__ import annotations
5from enum import IntEnum
7import msgspec
9from ..context import CharacteristicContext
10from .base import BaseCharacteristic
11from .utils import DataParser
14class ASEState(IntEnum):
15 """Audio Stream Endpoint state values."""
17 IDLE = 0x00
18 CODEC_CONFIGURED = 0x01
19 QOS_CONFIGURED = 0x02
20 ENABLING = 0x03
21 STREAMING = 0x04
22 DISABLING = 0x05
23 RELEASING = 0x06
26_ADDITIONAL_DATA_START_INDEX = 2
29class SinkASEData(msgspec.Struct, frozen=True, kw_only=True): # pylint: disable=too-few-public-methods
30 """Parsed data from Sink ASE characteristic.
32 Contains the ASE ID, current state, and any additional
33 state-specific data as raw bytes.
34 """
36 ase_id: int
37 ase_state: ASEState
38 additional_data: bytes = b""
41class SinkASECharacteristic(BaseCharacteristic[SinkASEData]):
42 """Sink ASE characteristic (0x2BC4).
44 org.bluetooth.characteristic.sink_ase
46 Audio Stream Endpoint for sink (audio receiver) role.
47 """
49 min_length = 2
50 allow_variable_length = True
52 def _decode_value(
53 self, data: bytearray, ctx: CharacteristicContext | None = None, *, validate: bool = True
54 ) -> SinkASEData:
55 """Parse Sink ASE data.
57 Format: ASE_ID (uint8) + ASE_State (uint8) + variable state-specific data.
58 """
59 ase_id = DataParser.parse_int8(data, 0, signed=False)
60 ase_state = ASEState(DataParser.parse_int8(data, 1, signed=False))
61 additional_data = (
62 bytes(data[_ADDITIONAL_DATA_START_INDEX:]) if len(data) > _ADDITIONAL_DATA_START_INDEX else b""
63 )
65 return SinkASEData(
66 ase_id=ase_id,
67 ase_state=ase_state,
68 additional_data=additional_data,
69 )
71 def _encode_value(self, data: SinkASEData) -> bytearray:
72 """Encode Sink ASE data to bytes."""
73 result = bytearray()
74 result += DataParser.encode_int8(data.ase_id)
75 result += DataParser.encode_int8(int(data.ase_state))
76 result += bytearray(data.additional_data)
77 return result