Coverage for src / bluetooth_sig / gatt / characteristics / acs_status.py: 100%
25 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-03 16:41 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-04-03 16:41 +0000
1"""ACS Status characteristic (0x2B2F)."""
3from __future__ import annotations
5import msgspec
7from ..context import CharacteristicContext
8from .base import BaseCharacteristic
9from .utils import DataParser
12class ACSStatusData(msgspec.Struct, frozen=True, kw_only=True):
13 """Parsed data from ACS Status characteristic."""
15 security_controls_switch: bool
16 security_established: bool
17 current_restriction_map_id: int
20class ACSStatusCharacteristic(BaseCharacteristic[ACSStatusData]):
21 """ACS Status characteristic (0x2B2F).
23 org.bluetooth.characteristic.acs_status
25 Contains ACS status flags and the current restriction map ID.
26 """
28 expected_length: int | None = 3
30 def _decode_value(
31 self, data: bytearray, ctx: CharacteristicContext | None = None, *, validate: bool = True
32 ) -> ACSStatusData:
33 status_flags = DataParser.parse_int8(data, 0, signed=False)
34 restriction_map_id = DataParser.parse_int16(data, 1, signed=False)
36 return ACSStatusData(
37 security_controls_switch=bool(status_flags & 0x01),
38 security_established=bool(status_flags & 0x02),
39 current_restriction_map_id=restriction_map_id,
40 )
42 def _encode_value(self, data: ACSStatusData) -> bytearray:
43 status_flags = 0
44 if data.security_controls_switch:
45 status_flags |= 0x01
46 if data.security_established:
47 status_flags |= 0x02
49 result = bytearray()
50 result.extend(DataParser.encode_int8(status_flags, signed=False))
51 result.extend(DataParser.encode_int16(data.current_restriction_map_id, signed=False))
52 return result