diff --git a/python_otbr_api/tlv_parser.py b/python_otbr_api/tlv_parser.py index 174e12e..c8d4cd4 100644 --- a/python_otbr_api/tlv_parser.py +++ b/python_otbr_api/tlv_parser.py @@ -115,7 +115,7 @@ def __post_init__(self) -> None: unpacked: int = struct.unpack("!Q", self.data)[0] self.authoritative = bool(unpacked & 1) self.seconds = unpacked >> 16 - self.ticks = (unpacked >> 1) & 0x7FF + self.ticks = (unpacked >> 1) & 0x7FFF def _encode_item(item: MeshcopTLVItem) -> bytes: diff --git a/tests/test_tlv_parser.py b/tests/test_tlv_parser.py index 21abc4e..ea698ec 100644 --- a/tests/test_tlv_parser.py +++ b/tests/test_tlv_parser.py @@ -156,3 +156,33 @@ def test_parse_tlv_error(tlv, error, msg) -> None: """Test the TLV parser error handling.""" with pytest.raises(error, match=msg): parse_tlv(tlv) + + +def test_timestamp_parsing_full_integrity() -> None: + """ + Test parsing of a timestamp with mixed values for seconds, ticks, and authoritative. + + We construct a value to ensure no bit overlap: + - Seconds: 400 (0x190) + - Ticks: 32767 (0x7FFF, Max value to catch the masking bug) + - Authoritative: True (1) + + Hex Construction: + - Seconds (48 bits): 00 00 00 00 01 90 + - Ticks/Auth (16 bits): + (Ticks << 1) | Auth + (0x7FFF << 1) | 1 => 0xFFFE | 1 => 0xFFFF + + Combined Hex: 000000000190FFFF + """ + timestamp_data = bytes.fromhex("000000000190FFFF") + timestamp = Timestamp(MeshcopTLVType.ACTIVETIMESTAMP, timestamp_data) + + # 1. Check Seconds: Ensures the upper 48 bits are shifted correctly + assert timestamp.seconds == 400 + + # 2. Check Ticks: Ensures the mask is 0x7FFF (32767) + assert timestamp.ticks == 32767 + + # 3. Check Authoritative: Ensures the lowest bit is read correctly + assert timestamp.authoritative is True