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

21 statements  

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

1"""Scan Interval Window characteristic implementation.""" 

2 

3from __future__ import annotations 

4 

5from ...types.gatt_enums import CharacteristicRole 

6from ...types.scan_interval_window import ScanIntervalWindowData 

7from ..context import CharacteristicContext 

8from .base import BaseCharacteristic 

9from .utils import DataParser 

10 

11 

12class ScanIntervalWindowCharacteristic(BaseCharacteristic[ScanIntervalWindowData]): 

13 """Scan Interval Window characteristic (0x2A4F). 

14 

15 org.bluetooth.characteristic.scan_interval_window 

16 

17 The Scan Interval Window characteristic is used to set the scan interval 

18 and scan window parameters for BLE scanning. 

19 

20 This is a write-only characteristic containing: 

21 - Scan Interval: uint16 (2 bytes, little-endian, units of 0.625ms, range 0x0004-0x4000) 

22 - Scan Window: uint16 (2 bytes, little-endian, units of 0.625ms, range 0x0004-0x4000) 

23 

24 The scan window must be less than or equal to the scan interval. 

25 """ 

26 

27 _manual_role = CharacteristicRole.INFO 

28 _characteristic_name = "Scan Interval Window" 

29 

30 min_length = 4 # Scan Interval(2) + Scan Window(2) 

31 max_length = 4 # Fixed length 

32 allow_variable_length: bool = False # Fixed length 

33 

34 def _decode_value( 

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

36 ) -> ScanIntervalWindowData: 

37 """Parse scan interval window data. 

38 

39 Args: 

40 data: Raw bytearray from BLE characteristic (4 bytes). 

41 ctx: Optional CharacteristicContext providing surrounding context (may be None). 

42 validate: Whether to validate ranges (default True) 

43 

44 Returns: 

45 ScanIntervalWindowData with parsed scan parameters. 

46 

47 """ 

48 scan_interval = DataParser.parse_int16(data, 0, signed=False) 

49 scan_window = DataParser.parse_int16(data, 2, signed=False) 

50 

51 return ScanIntervalWindowData(scan_interval=scan_interval, scan_window=scan_window) 

52 

53 def _encode_value(self, data: ScanIntervalWindowData) -> bytearray: 

54 """Encode scan interval window value back to bytes. 

55 

56 Args: 

57 data: ScanIntervalWindowData instance 

58 

59 Returns: 

60 Encoded bytes representing the scan parameters (4 bytes) 

61 

62 """ 

63 result = bytearray() 

64 result.extend(DataParser.encode_int16(data.scan_interval, signed=False)) 

65 result.extend(DataParser.encode_int16(data.scan_window, signed=False)) 

66 return result