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

23 statements  

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

1"""BSS Response characteristic (0x2B2C). 

2 

3Response characteristic for the Binary Sensor Service. 

4 

5The BSS protocol uses Split Header + Payload format. Responses and 

6unsolicited events are indicated via this characteristic. 

7 

8References: 

9 Bluetooth SIG Binary Sensor Service 1.0, Sections 3.2 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 BSSResponseData(msgspec.Struct, frozen=True, kw_only=True): 

23 """Parsed data from BSS Response. 

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 BSSResponseCharacteristic(BaseCharacteristic[BSSResponseData]): 

36 """BSS Response characteristic (0x2B2C). 

37 

38 org.bluetooth.characteristic.bss_response 

39 

40 Sends responses and unsolicited events from the Binary Sensor 

41 Service using Split Header + Payload format. 

42 

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

44 ``GET_SENSOR_STATUS_RESPONSE``, ``SETTING_SENSOR_RESPONSE``, 

45 and ``SENSOR_STATUS_EVENT``. 

46 """ 

47 

48 min_length = 1 

49 max_length = 20 

50 allow_variable_length = True 

51 

52 def _decode_value( 

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

54 ) -> BSSResponseData: 

55 """Parse BSS Response data. 

56 

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

58 """ 

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

60 split_header = SplitHeader.from_byte(raw_header) 

61 payload = bytes(data[1:]) 

62 

63 return BSSResponseData( 

64 split_header=split_header, 

65 payload=payload, 

66 ) 

67 

68 def _encode_value(self, data: BSSResponseData) -> bytearray: 

69 """Encode BSS Response data.""" 

70 result = bytearray() 

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

72 result.extend(data.payload) 

73 return result