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

1"""TDS Control Point characteristic (0x2ABC).""" 

2 

3from __future__ import annotations 

4 

5from enum import IntEnum 

6 

7import msgspec 

8 

9from ..context import CharacteristicContext 

10from .base import BaseCharacteristic 

11from .utils import DataParser 

12 

13 

14class TDSControlPointOpCode(IntEnum): 

15 """TDS Control Point operation codes.""" 

16 

17 ACTIVATE_TRANSPORT = 0x01 

18 

19 

20_PARAMETER_START_INDEX = 2 

21 

22 

23class TDSControlPointData(msgspec.Struct, frozen=True, kw_only=True): 

24 """Parsed data from TDS Control Point characteristic.""" 

25 

26 op_code: TDSControlPointOpCode 

27 organization_id: int 

28 parameter: bytes | None = None 

29 

30 

31class TDSControlPointCharacteristic(BaseCharacteristic[TDSControlPointData]): 

32 """TDS Control Point characteristic (0x2ABC). 

33 

34 org.bluetooth.characteristic.tds_control_point 

35 

36 Used to activate a transport on the Transport Discovery Service. 

37 """ 

38 

39 min_length = 2 

40 allow_variable_length = True 

41 

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 

48 

49 return TDSControlPointData( 

50 op_code=op_code, 

51 organization_id=organization_id, 

52 parameter=parameter, 

53 ) 

54 

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