From c88dff148b9b8da24abfde76067152c94cc629ea Mon Sep 17 00:00:00 2001 From: Jorge Antonio Diaz-Benito Soriano Date: Tue, 7 Nov 2023 20:21:37 +0100 Subject: [PATCH] Fix deserialization logic for mode, stratum, poll and precision --- .../internal/NtpPacketDeserializer.kt | 44 +++++++++++++++++-- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/library/src/commonMain/kotlin/com/tidal/networktime/internal/NtpPacketDeserializer.kt b/library/src/commonMain/kotlin/com/tidal/networktime/internal/NtpPacketDeserializer.kt index 2ace96b4..ab5bfeb2 100644 --- a/library/src/commonMain/kotlin/com/tidal/networktime/internal/NtpPacketDeserializer.kt +++ b/library/src/commonMain/kotlin/com/tidal/networktime/internal/NtpPacketDeserializer.kt @@ -7,7 +7,21 @@ import kotlin.time.Duration.Companion.seconds internal class NtpPacketDeserializer { operator fun invoke(bytes: ByteArray): NtpPacket? { - val bits = bytes.flatMap { it.toString(2).asIterable() } + val bits = bytes.map { it.toInt() } + .flatMap { + listOf( + it and 1, + it and (1 shl 1), + it and (1 shl 2), + it and (1 shl 3), + it and (1 shl 4), + it and (1 shl 5), + it and (1 shl 6), + it and (1 shl 7), + ).map { + it != 0 + } + } var startIndexInclusive = 0 var endIndexExclusive = 2 var index = 0 @@ -18,6 +32,21 @@ internal class NtpPacketDeserializer { startIndexInclusive = endIndexExclusive endIndexExclusive += 3 val versionNumber = bits.bitRangeAsInt(startIndexInclusive until endIndexExclusive) + startIndexInclusive = endIndexExclusive + endIndexExclusive += 3 + val mode = bits.bitRangeAsInt(startIndexInclusive until endIndexExclusive) + startIndexInclusive = endIndexExclusive + endIndexExclusive += 8 + val stratum = bytes[1].asInt + if (stratum >= STRATUM_CLOCK_NOT_SYNCHRONIZED) { + return null + } + startIndexInclusive = endIndexExclusive + endIndexExclusive += 8 + val poll = bytes[2].asInt + startIndexInclusive = endIndexExclusive + endIndexExclusive += 8 + val precision = bytes[3].asInt return NtpPacket( (bytes[index++].toInt() shl 8) + bytes[index++], (bytes[index++].toInt() shl 16) + (bytes[index++].toInt() shl 24) + bytes[index++], @@ -41,8 +70,16 @@ internal class NtpPacketDeserializer { ) } - private fun List.bitRangeAsInt(intRange: IntRange) = - subList(intRange.first, intRange.last + 1).joinToString(separator = "").toInt(2) + private fun List.bitRangeAsInt(intRange: IntRange) = + subList(intRange.first, intRange.last + 1).foldIndexed(0) { i, acc, it -> + when (it) { + true -> 2F.pow(i).toInt() + false -> 0 + } + acc + } + + private val Byte.asInt + get() = toUByte().toInt() private val ByteArray.asNtpIntervalToInterval: Duration get() { @@ -86,5 +123,6 @@ internal class NtpPacketDeserializer { companion object { private const val LEAP_INDICATOR_CLOCK_UNSYNCHRONIZED = 0b11 + private const val STRATUM_CLOCK_NOT_SYNCHRONIZED = 16 } }