How does NTP work?
NTP uses UDP/IP packets for data transfer because of the fast connection setup and response times.
The official port number for the NTP (that ntpd and ntpdate listen and talk to) is 123.
The unit of time is in seconds, and the epoch is 1 January 1900.
its gives you UTC time, which is the time at Greenwich Meridian (GMT)
The NTP timestamp is a 64-bit binary value, built from an unsigned 32-bit seconds value
and a 32-bit fractional part. In this notation the value 3.5 would be represented by the 64-bit string:
0000|0000|0000|0000|0000|0000|0000|0011 . 1000|0000|0000|0000|0000|0000|0000|0000
If you take all the bits as a 64-bit unsigned integer,
store it in a floating-point variable with at least 64 bits of mantissa (usually double)
and do a floating-point divide by 2^32, you'll get the right answer.
On a standard Arduino, unfortunately, we don't have 64 bits doubles.
but most RTC have just second level info, so no need to get the second half (or first byte possibly)
Only the first four bytes of an outgoing NTP packet need to be set for what we want to achieve
appropriately, the rest can be whatever.
The header fields of the NTP message are as follows:
LI Leap Indicator (2 bits)
This field indicates whether the last minute of the current day is to have a leap second applied. The field values follow:
0: No leap second adjustment
1: Last-minute of the day has 61 seconds
2: Last-minute of the day has 59 seconds
3: Clock is unsynchronized
VN NTP Version Number (3 bits) (current version is 4).
Mode NTP packet mode (3 bits)
The values of the Mode field follow:
1: Symmetric active
2: Symmetric passive
6: NTP control message
7: Reserved for private use
Stratum level of the time source (8 bits)
The values of the Stratum field follow:
0: Unspecified or invalid
1: Primary server
2–15: Secondary server
Poll Poll interval (8-bit signed integer)
The log2 value of the maximum interval between successive NTP messages, in seconds.
Precision Clock precision (8-bit signed integer)
The precision of the system clock, in log2 seconds.
NTP First Four Bytes 0xEC0600E3 This is the NTP request header but we only need the first 32 bits
We define the NTP PACKET SIZE this is 48 bytes because the NTP time stamp is in the first 48 bytes of the message
after a successful query, we will get a 48-byte answer from the NTP server.
To understand the structure of an NTP query and answer
so if we want to read the "Transmit Timestamp" then we need to
Read the integer part which is bytes 40,41,42,43
if we want to round to the nearest second if we want some accuracy
Then fractional part are byte 44,45,46,47
if it is greater than 500ms byte 44 will be > 128
and thus by only checking byte 44 of the answer, we can round to the next second;
90% of the NTP servers have network delays below 100ms
We can also account for an assumed averaged network delay of 50ms, and thus instead of
comparing with 128 you can compare with (0.5s - 0.05s) * 256 = 115;