Coverage for src / bluetooth_sig / types / advertising / three_d_information.py: 100%

30 statements  

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

1"""3D Information Data (AD 0x3D, CSS Part A §1.13). 

2 

3Decodes the 3D Information Data AD type used for 3D display 

4synchronisation between a 3D display and 3D glasses. 

5""" 

6 

7from __future__ import annotations 

8 

9from enum import IntFlag 

10 

11import msgspec 

12 

13from bluetooth_sig.gatt.characteristics.utils import DataParser 

14 

15 

16class ThreeDInformationFlags(IntFlag): 

17 """3D Information Data flags byte (CSS Part A §1.13). 

18 

19 Bit assignments from the 3D Synchronisation Profile specification. 

20 """ 

21 

22 ASSOCIATION_NOTIFICATION = 0x01 # Bit 0: send association notification 

23 BATTERY_LEVEL_REPORTING = 0x02 # Bit 1: device reports battery level 

24 SEND_BATTERY_ON_STARTUP = 0x04 # Bit 2: send battery level on startup 

25 FACTORY_TEST_MODE = 0x80 # Bit 7: factory test mode enabled 

26 

27 

28class ThreeDInformationData(msgspec.Struct, frozen=True, kw_only=True): 

29 """Parsed 3D Information Data for 3D display synchronisation (CSS Part A, §1.13). 

30 

31 Format: flags (1 byte) + path_loss_threshold (1 byte). 

32 

33 Attributes: 

34 flags: Raw flags for reference and bitwise queries. 

35 path_loss_threshold: Path-loss threshold in dBm for proximity detection. 

36 

37 """ 

38 

39 flags: ThreeDInformationFlags = ThreeDInformationFlags(0) 

40 path_loss_threshold: int = 0 

41 

42 @property 

43 def association_notification(self) -> bool: 

44 """Whether association notification is enabled (bit 0).""" 

45 return bool(self.flags & ThreeDInformationFlags.ASSOCIATION_NOTIFICATION) 

46 

47 @property 

48 def battery_level_reporting(self) -> bool: 

49 """Whether battery level reporting is enabled (bit 1).""" 

50 return bool(self.flags & ThreeDInformationFlags.BATTERY_LEVEL_REPORTING) 

51 

52 @property 

53 def send_battery_on_startup(self) -> bool: 

54 """Whether battery level is sent on startup (bit 2).""" 

55 return bool(self.flags & ThreeDInformationFlags.SEND_BATTERY_ON_STARTUP) 

56 

57 @property 

58 def factory_test_mode(self) -> bool: 

59 """Whether factory test mode is enabled (bit 7).""" 

60 return bool(self.flags & ThreeDInformationFlags.FACTORY_TEST_MODE) 

61 

62 @classmethod 

63 def decode(cls, data: bytes | bytearray) -> ThreeDInformationData: 

64 """Decode 3D Information Data AD. 

65 

66 DataParser raises ``InsufficientDataError`` if fewer than 2 bytes 

67 are available. 

68 

69 Args: 

70 data: Raw AD data bytes (excluding length and AD type). 

71 

72 Returns: 

73 Parsed ThreeDInformationData. 

74 

75 """ 

76 flags = ThreeDInformationFlags(DataParser.parse_int8(data, 0, signed=False)) 

77 path_loss = DataParser.parse_int8(data, 1, signed=False) 

78 

79 return cls(flags=flags, path_loss_threshold=path_loss) 

80 

81 

82__all__ = [ 

83 "ThreeDInformationData", 

84 "ThreeDInformationFlags", 

85]