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

35 statements  

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

1"""OTS Feature characteristic (0x2ABD).""" 

2 

3from __future__ import annotations 

4 

5from enum import IntFlag 

6 

7import msgspec 

8 

9from ..context import CharacteristicContext 

10from .base import BaseCharacteristic 

11 

12 

13class OACPFeatures(IntFlag): 

14 """Object Action Control Point feature flags.""" 

15 

16 CREATE = 0x00000001 

17 DELETE = 0x00000002 

18 CALCULATE_CHECKSUM = 0x00000004 

19 EXECUTE = 0x00000008 

20 READ = 0x00000010 

21 WRITE = 0x00000020 

22 APPEND = 0x00000040 

23 TRUNCATE = 0x00000080 

24 PATCH = 0x00000100 

25 ABORT = 0x00000200 

26 

27 

28class OLCPFeatures(IntFlag): 

29 """Object List Control Point feature flags.""" 

30 

31 GO_TO = 0x00000001 

32 ORDER = 0x00000002 

33 REQUEST_NUMBER_OF_OBJECTS = 0x00000004 

34 CLEAR_MARKING = 0x00000008 

35 

36 

37class OTSFeatureData(msgspec.Struct, frozen=True): 

38 """OTS Feature characteristic data. 

39 

40 Attributes: 

41 oacp_features: OACP features bitmap (uint32). 

42 olcp_features: OLCP features bitmap (uint32). 

43 """ 

44 

45 oacp_features: OACPFeatures 

46 olcp_features: OLCPFeatures 

47 

48 

49class OTSFeatureCharacteristic(BaseCharacteristic[OTSFeatureData]): 

50 """OTS Feature characteristic (0x2ABD). 

51 

52 org.bluetooth.characteristic.ots_feature 

53 

54 Contains two uint32 fields: OACP features and OLCP features. 

55 """ 

56 

57 expected_length: int = 8 

58 

59 def _decode_value( 

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

61 ) -> OTSFeatureData: 

62 oacp = OACPFeatures(int.from_bytes(data[0:4], byteorder="little", signed=False)) 

63 olcp = OLCPFeatures(int.from_bytes(data[4:8], byteorder="little", signed=False)) 

64 return OTSFeatureData(oacp_features=oacp, olcp_features=olcp) 

65 

66 def _encode_value(self, data: OTSFeatureData) -> bytearray: 

67 result = bytearray() 

68 result.extend(int(data.oacp_features).to_bytes(4, byteorder="little", signed=False)) 

69 result.extend(int(data.olcp_features).to_bytes(4, byteorder="little", signed=False)) 

70 return result