Coverage for src / bluetooth_sig / gatt / characteristics / termination_reason.py: 100%
31 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"""Termination Reason characteristic (0x2BC0)."""
3from __future__ import annotations
5from enum import IntEnum
7import msgspec
9from ..context import CharacteristicContext
10from .base import BaseCharacteristic
11from .utils import DataParser
14class TerminationReason(IntEnum):
15 """Call termination reason as per TBS 1.0, Table 3.14."""
17 INVALID_URI = 0x00
18 CALL_FAILED = 0x01
19 REMOTE_PARTY_ENDED = 0x02
20 SERVER_ENDED = 0x03
21 LINE_BUSY = 0x04
22 NETWORK_CONGESTION = 0x05
23 CLIENT_ENDED = 0x06
24 NO_SERVICE = 0x07
25 NO_ANSWER = 0x08
26 UNSPECIFIED = 0x09
29class TerminationReasonData(msgspec.Struct, frozen=True, kw_only=True):
30 """Parsed data from Termination Reason characteristic."""
32 call_index: int
33 reason: TerminationReason
36class TerminationReasonCharacteristic(BaseCharacteristic[TerminationReasonData]):
37 """Termination Reason characteristic (0x2BC0).
39 org.bluetooth.characteristic.termination_reason
41 Call Index (uint8) followed by Reason Code (uint8).
43 References:
44 Telephone Bearer Service 1.0, Section 3.16
45 """
47 expected_length: int = 2
49 def _decode_value(
50 self, data: bytearray, ctx: CharacteristicContext | None = None, *, validate: bool = True
51 ) -> TerminationReasonData:
52 call_index = DataParser.parse_int8(data, 0, signed=False)
53 reason = TerminationReason(DataParser.parse_int8(data, 1, signed=False))
55 return TerminationReasonData(call_index=call_index, reason=reason)
57 def _encode_value(self, data: TerminationReasonData) -> bytearray:
58 result = bytearray()
59 result.extend(DataParser.encode_int8(data.call_index, signed=False))
60 result.extend(DataParser.encode_int8(int(data.reason), signed=False))
61 return result