Coverage for src / bluetooth_sig / gatt / characteristics / service_changed.py: 100%
20 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-11 20:14 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-01-11 20:14 +0000
1"""Service Changed characteristic implementation."""
3from __future__ import annotations
5import msgspec
7from ..context import CharacteristicContext
8from .base import BaseCharacteristic
9from .utils import DataParser
12class ServiceChangedData(msgspec.Struct, frozen=True, kw_only=True):
13 """Service Changed characteristic data.
15 Attributes:
16 start_handle: Starting handle of the affected service range
17 end_handle: Ending handle of the affected service range
18 """
20 start_handle: int
21 end_handle: int
24class ServiceChangedCharacteristic(BaseCharacteristic[ServiceChangedData]):
25 """Service Changed characteristic (0x2A05).
27 org.bluetooth.characteristic.gatt.service_changed
29 Service Changed characteristic.
30 """
32 _manual_value_type = "ServiceChangedData"
34 expected_length = 4
36 def _decode_value(self, data: bytearray, ctx: CharacteristicContext | None = None) -> ServiceChangedData:
37 """Parse service changed value.
39 Args:
40 data: Raw bytearray from BLE characteristic.
41 ctx: Optional CharacteristicContext providing surrounding context (may be None).
43 Returns:
44 ServiceChangedData with start_handle and end_handle.
45 """
46 start_handle = DataParser.parse_int16(data, 0, signed=False)
47 end_handle = DataParser.parse_int16(data, 2, signed=False)
48 return ServiceChangedData(start_handle=start_handle, end_handle=end_handle)
50 def _encode_value(self, data: ServiceChangedData) -> bytearray:
51 """Encode service changed value back to bytes.
53 Args:
54 data: ServiceChangedData with start_handle and end_handle
56 Returns:
57 Encoded bytes
58 """
59 result = bytearray()
60 result.extend(DataParser.encode_int16(data.start_handle, signed=False))
61 result.extend(DataParser.encode_int16(data.end_handle, signed=False))
62 return result