Sub Class_Globals
Private OFFSET_1900_TO_1970 As Long = 2208988800
Private no As NativeObject
Private NtpTime, RoundTripTime, NtpTimeReference As Long
End Sub
Public Sub Initialize
no = Me
End Sub
Public Sub UpdateOffsets As ResumableSub
Dim us As UDPSocket
us.Initialize("us", 0, 8192)
Dim RequestData(48) As Byte
Dim raf As RandomAccessFile
raf.Initialize3(RequestData, False)
Dim time As Long = DateTime.Now
Dim seconds As Long = time / 1000
Dim milliseconds As Long = time - seconds * 1000
seconds = seconds + OFFSET_1900_TO_1970
raf.WriteByte(27, 0)
raf.WriteInt(seconds, 40)
Dim fraction As Long = milliseconds * 4294967
raf.WriteInt(fraction, raf.CurrentPosition)
raf.WriteByte(Rnd(0, 256), 47)
Dim packet As UDPPacket
packet.Initialize(RequestData, "0.pool.ntp.org", 123)
us.Send(packet)
Wait For us_PacketArrived (packet As UDPPacket)
raf.Initialize3(packet.Data, False)
Dim responseTime As Long = DateTime.Now
Dim originateTime As Long = ReadTimeStamp(raf, 24)
Dim receiveTime As Long = ReadTimeStamp(raf, 32)
Dim transmitTime As Long = ReadTimeStamp(raf, 40)
RoundTripTime = responseTime - time
Dim clockOffset As Long = (receiveTime - originateTime + transmitTime - responseTime) / 2
NtpTime = responseTime + clockOffset
NtpTimeReference = responseTime
us.Close
Return True
End Sub
Public Sub getNow As Long
If NtpTime = 0 Then
Log("Time not available.")
Return DateTime.Now
End If
Return NtpTime + DateTime.Now - NtpTimeReference
End Sub
Private Sub ReadTimeStamp (raf As RandomAccessFile, Offset As Int) As Long
Dim seconds As Long = Read32(raf, Offset)
Dim fraction As Long = Read32(raf, Offset + 4)
Return ((seconds - OFFSET_1900_TO_1970) * 1000) + ((fraction * 1000) / 4294967296)
End Sub
Private Sub Read32(raf As RandomAccessFile, Offset As Int) As Long
Dim i0 As Int = raf.ReadUnsignedByte(Offset)
Dim i1 As Int = raf.ReadUnsignedByte(raf.CurrentPosition)
Dim i2 As Int = raf.ReadUnsignedByte(raf.CurrentPosition)
Dim i3 As Int = raf.ReadUnsignedByte(raf.CurrentPosition)
Return ShiftLeftLong(i0, 24) + ShiftLeftLong(i1, 16) + ShiftLeftLong(i2, 8) + i3
End Sub
Private Sub ShiftLeftLong(N As Long, Count As Int) As Long
Return Bit.ShiftLeft(N, Count)
End Sub