Coverage for src / bluetooth_sig / gatt / characteristics / tds_control_point.py: 100%
28 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"""TDS Control Point characteristic (0x2ABC)."""
3from __future__ import annotations
5from enum import IntEnum
7import msgspec
9from ..context import CharacteristicContext
10from .base import BaseCharacteristic
11from .utils import DataParser
14class TDSControlPointOpCode(IntEnum):
15 """TDS Control Point operation codes."""
17 ACTIVATE_TRANSPORT = 0x01
20_PARAMETER_START_INDEX = 2
23class TDSControlPointData(msgspec.Struct, frozen=True, kw_only=True):
24 """Parsed data from TDS Control Point characteristic."""
26 op_code: TDSControlPointOpCode
27 organization_id: int
28 parameter: bytes | None = None
31class TDSControlPointCharacteristic(BaseCharacteristic[TDSControlPointData]):
32 """TDS Control Point characteristic (0x2ABC).
34 org.bluetooth.characteristic.tds_control_point
36 Used to activate a transport on the Transport Discovery Service.
37 """
39 min_length = 2
40 allow_variable_length = True
42 def _decode_value(
43 self, data: bytearray, ctx: CharacteristicContext | None = None, *, validate: bool = True
44 ) -> TDSControlPointData:
45 op_code = TDSControlPointOpCode(DataParser.parse_int8(data, 0, signed=False))
46 organization_id = DataParser.parse_int8(data, 1, signed=False)
47 parameter = bytes(data[_PARAMETER_START_INDEX:]) if len(data) > _PARAMETER_START_INDEX else None
49 return TDSControlPointData(
50 op_code=op_code,
51 organization_id=organization_id,
52 parameter=parameter,
53 )
55 def _encode_value(self, data: TDSControlPointData) -> bytearray:
56 result = bytearray()
57 result.append(int(data.op_code))
58 result.extend(DataParser.encode_int8(data.organization_id, signed=False))
59 if data.parameter is not None:
60 result.extend(data.parameter)
61 return result