Skip to content

Commit 79341ca

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 79341ca

File tree

2 files changed

+29
-1
lines changed

2 files changed

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

0 commit comments

Comments
 (0)