Skip to content

Commit f2d5e02

Browse files
committed
Fix timestamp ticks decoding mask
Thread defines the Timestamp Ticks field as 15 bits. The parser was using a mask of `0x7FF` (11 bits), which truncated higher tick values. This changes the mask to `0x7FFF` to correctly decode the full 15-bit value. Related to home-assistant/core#134306
1 parent fdbbebe commit f2d5e02

File tree

2 files changed

+31
-1
lines changed

2 files changed

+31
-1
lines changed

python_otbr_api/tlv_parser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ def __post_init__(self) -> None:
115115
unpacked: int = struct.unpack("!Q", self.data)[0]
116116
self.authoritative = bool(unpacked & 1)
117117
self.seconds = unpacked >> 16
118-
self.ticks = (unpacked >> 1) & 0x7FF
118+
self.ticks = (unpacked >> 1) & 0x7FFF
119119

120120

121121
def _encode_item(item: MeshcopTLVItem) -> bytes:

tests/test_tlv_parser.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,3 +156,33 @@ def test_parse_tlv_error(tlv, error, msg) -> None:
156156
"""Test the TLV parser error handling."""
157157
with pytest.raises(error, match=msg):
158158
parse_tlv(tlv)
159+
160+
161+
def test_timestamp_parsing_full_integrity() -> None:
162+
"""
163+
Test parsing of a timestamp with mixed values for seconds, ticks, and authoritative.
164+
165+
We construct a value to ensure no bit overlap:
166+
- Seconds: 400 (0x190)
167+
- Ticks: 32767 (0x7FFF, Max value to catch the masking bug)
168+
- Authoritative: True (1)
169+
170+
Hex Construction:
171+
- Seconds (48 bits): 00 00 00 00 01 90
172+
- Ticks/Auth (16 bits):
173+
(Ticks << 1) | Auth
174+
(0x7FFF << 1) | 1 => 0xFFFE | 1 => 0xFFFF
175+
176+
Combined Hex: 000000000190FFFF
177+
"""
178+
timestamp_data = bytes.fromhex("000000000190FFFF")
179+
timestamp = Timestamp(MeshcopTLVType.ACTIVETIMESTAMP, timestamp_data)
180+
181+
# 1. Check Seconds: Ensures the upper 48 bits are shifted correctly
182+
assert timestamp.seconds == 400
183+
184+
# 2. Check Ticks: Ensures the mask is 0x7FFF (32767)
185+
assert timestamp.ticks == 32767
186+
187+
# 3. Check Authoritative: Ensures the lowest bit is read correctly
188+
assert timestamp.authoritative is True

0 commit comments

Comments
 (0)