Coverage for src / bluetooth_sig / gatt / characteristics / bss_control_point.py: 100%

23 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-04-03 16:41 +0000

1"""BSS Control Point characteristic (0x2B2B). 

2 

3Control point for the Binary Sensor Service. 

4 

5The BSS protocol uses Split Header + Payload format. Messages contain 

6a Message ID, Number of Parameters, and TLV-encoded parameters. 

7 

8References: 

9 Bluetooth SIG Binary Sensor Service 1.0, Sections 3.1 and 4 

10""" 

11 

12from __future__ import annotations 

13 

14import msgspec 

15 

16from ...types.bss import SplitHeader 

17from ..context import CharacteristicContext 

18from .base import BaseCharacteristic 

19from .utils import DataParser 

20 

21 

22class BSSControlPointData(msgspec.Struct, frozen=True, kw_only=True): 

23 """Parsed data from BSS Control Point. 

24 

25 Attributes: 

26 split_header: Parsed Split Header fields. 

27 payload: Raw payload bytes (message content). Empty if none. 

28 

29 """ 

30 

31 split_header: SplitHeader 

32 payload: bytes = b"" 

33 

34 

35class BSSControlPointCharacteristic(BaseCharacteristic[BSSControlPointData]): 

36 """BSS Control Point characteristic (0x2B2B). 

37 

38 org.bluetooth.characteristic.bss_control_point 

39 

40 Receives commands for the Binary Sensor Service using Split Header + 

41 Payload format. 

42 

43 Command message IDs are defined in ``BSSMessageID``: 

44 ``GET_SENSOR_STATUS_COMMAND`` and ``SETTING_SENSOR_COMMAND``. 

45 """ 

46 

47 min_length = 1 

48 max_length = 20 

49 allow_variable_length = True 

50 

51 def _decode_value( 

52 self, data: bytearray, ctx: CharacteristicContext | None = None, *, validate: bool = True 

53 ) -> BSSControlPointData: 

54 """Parse BSS Control Point data. 

55 

56 Format: Split Header (uint8) + Payload (1-19 octets). 

57 """ 

58 raw_header = DataParser.parse_int8(data, 0, signed=False) 

59 split_header = SplitHeader.from_byte(raw_header) 

60 payload = bytes(data[1:]) 

61 

62 return BSSControlPointData( 

63 split_header=split_header, 

64 payload=payload, 

65 ) 

66 

67 def _encode_value(self, data: BSSControlPointData) -> bytearray: 

68 """Encode BSS Control Point data.""" 

69 result = bytearray() 

70 result.extend(DataParser.encode_int8(data.split_header.to_byte(), signed=False)) 

71 result.extend(data.payload) 

72 return result