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

24 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-03-18 11:17 +0000

1"""Bond Management Feature characteristic implementation.""" 

2 

3from __future__ import annotations 

4 

5import msgspec 

6 

7from ..context import CharacteristicContext 

8from .base import BaseCharacteristic 

9from .utils import DataParser 

10 

11 

12class BondManagementFeatureData(msgspec.Struct, frozen=True, kw_only=True): 

13 """Bond Management Feature characteristic data structure.""" 

14 

15 delete_bond_of_requesting_device_supported: bool 

16 delete_all_bonds_on_server_supported: bool 

17 delete_all_but_active_bond_on_server_supported: bool 

18 

19 

20class BondManagementFeatureCharacteristic(BaseCharacteristic[BondManagementFeatureData]): 

21 """Bond Management Feature characteristic (0x2AA5). 

22 

23 org.bluetooth.characteristic.bond_management_feature 

24 

25 Read-only characteristic containing feature flags for bond management operations. 

26 3 bytes containing boolean flags for supported operations. 

27 """ 

28 

29 # SIG spec: three uint8 feature flags → fixed 3-byte payload; no GSS YAML 

30 expected_length = 3 

31 min_length = 3 

32 max_length = 3 

33 

34 def _decode_value( 

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

36 ) -> BondManagementFeatureData: 

37 """Decode Bond Management Feature data from bytes. 

38 

39 Args: 

40 data: Raw characteristic data (3 bytes) 

41 ctx: Optional characteristic context 

42 validate: Whether to validate ranges (default True) 

43 

44 Returns: 

45 BondManagementFeatureData with feature flags 

46 

47 Raises: 

48 ValueError: If data is insufficient 

49 

50 """ 

51 # Parse feature flags (1 byte each) 

52 delete_bond_supported = bool(DataParser.parse_int8(data, 0, signed=False)) 

53 delete_all_bonds_supported = bool(DataParser.parse_int8(data, 1, signed=False)) 

54 delete_all_but_active_supported = bool(DataParser.parse_int8(data, 2, signed=False)) 

55 

56 return BondManagementFeatureData( 

57 delete_bond_of_requesting_device_supported=delete_bond_supported, 

58 delete_all_bonds_on_server_supported=delete_all_bonds_supported, 

59 delete_all_but_active_bond_on_server_supported=delete_all_but_active_supported, 

60 ) 

61 

62 def _encode_value(self, data: BondManagementFeatureData) -> bytearray: 

63 """Encode Bond Management Feature data to bytes. 

64 

65 Args: 

66 data: BondManagementFeatureData to encode 

67 

68 validate: Whether to validate ranges (default True) 

69 

70 Returns: 

71 Encoded feature flags (3 bytes) 

72 

73 """ 

74 result = bytearray() 

75 

76 # Encode feature flags (1 byte each) 

77 result.append(1 if data.delete_bond_of_requesting_device_supported else 0) 

78 result.append(1 if data.delete_all_bonds_on_server_supported else 0) 

79 result.append(1 if data.delete_all_but_active_bond_on_server_supported else 0) 

80 

81 return result