diff --git a/NTP.cpp b/NTP.cpp index e0d873e..d113e86 100755 --- a/NTP.cpp +++ b/NTP.cpp @@ -73,8 +73,17 @@ bool NTP::update() { } bool NTP::ntpUpdate() { - if (server == nullptr) udp->beginPacket(serverIP, NTP_PORT); + if (server == nullptr) udp->beginPacket(serverIP, NTP_PORT); else udp->beginPacket(server, NTP_PORT); + // We set the transmit timestamp to be able to pick the + // correct response packet in case of previous responses arriving + // later. Sine the transmit timestamp is just copied verbatim + // into the response origin timestamp but otherwise not used + // it can be any number, and in particular does not nned to be + // an ntp-style timestamp. + const int64_t transmit_ts = micros(); + // Set transmit ts, offset in packet is 40, i.e. 10 32-bit words + *reinterpret_cast(ntpRequest + 10*4) = transmit_ts; udp->write(ntpRequest, NTP_PACKET_SIZE); udp->endPacket(); uint8_t timeout = 0; @@ -84,9 +93,15 @@ bool NTP::ntpUpdate() { size = udp->parsePacket(); if (timeout > 100) return false; timeout++; - } while (size != 48); + if (size == 48) { + udp->read(ntpQuery, NTP_PACKET_SIZE); + } + } while (size != 48 || + // Check returned originate timestamp also matches + // transmit_ts. Originate timestamp is 6 32 bit words + // into packet. + *reinterpret_cast(ntpQuery + 6*4) != transmit_ts); lastUpdate = millis() - (10 * (timeout + 1)); - udp->read(ntpQuery, NTP_PACKET_SIZE); #ifdef __AVR__ unsigned long highWord = word(ntpQuery[40], ntpQuery[41]); unsigned long lowWord = word(ntpQuery[42], ntpQuery[43]); diff --git a/NTP.h b/NTP.h index e889e87..f48b647 100755 --- a/NTP.h +++ b/NTP.h @@ -249,8 +249,8 @@ class NTP { UDP *udp; const char* server = nullptr; IPAddress serverIP; - uint8_t ntpRequest[NTP_PACKET_SIZE]; // = {0xE3, 0x00, 0x06, 0xEC}; - uint8_t ntpQuery[NTP_PACKET_SIZE]; + uint8_t ntpRequest[NTP_PACKET_SIZE] __attribute__((aligned(4))); // = {0xE3, 0x00, 0x06, 0xEC}; + uint8_t ntpQuery[NTP_PACKET_SIZE] __attribute__((aligned(4))); time_t utcCurrent = 0; time_t local = 0; struct tm *current;