Skip to content

Commit

Permalink
Merge pull request #33 from BugerDread/master
Browse files Browse the repository at this point in the history
Fix for issue #25
  • Loading branch information
ropg committed Mar 25, 2019
2 parents a60193f + 17ed421 commit de16d0b
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 9 deletions.
50 changes: 43 additions & 7 deletions src/ezTime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@ namespace ezt {
case CACHE_TOO_SMALL: return F("Cache too small");
case TOO_MANY_EVENTS: return F("Too many events");
case SERVER_ERROR: return _server_error;
case INVALID_DATA: return F("Invalid data received from NTP server");
default: return F("Unkown error");
}
}
Expand Down Expand Up @@ -470,20 +471,55 @@ namespace ezt {
}
}
udp.read(buffer, NTP_PACKET_SIZE);
uint32_t highWord, lowWord;
highWord = ( buffer[40] << 8 | buffer[41] ) & 0x0000FFFF; // Must be done in two steps on AVR
udp.stop(); // On AVR there's only very limited sockets, we want to free them when done.

//print out received packet for debug
int i;
debug(F("Received data:"));
for (i = 0; i < NTP_PACKET_SIZE; i++) {
if ((i % 4) == 0) {
debugln();
debug(String(i) + ": ");
}
debug(buffer[i], HEX);
debug(F(", "));
}
debugln();

//prepare timestamps
uint32_t highWord, lowWord;
highWord = ( buffer[16] << 8 | buffer[17] ) & 0x0000FFFF;
lowWord = ( buffer[18] << 8 | buffer[19] ) & 0x0000FFFF;
uint32_t reftsSec = highWord << 16 | lowWord; // reference timestamp seconds

highWord = ( buffer[32] << 8 | buffer[33] ) & 0x0000FFFF;
lowWord = ( buffer[34] << 8 | buffer[35] ) & 0x0000FFFF;
uint32_t rcvtsSec = highWord << 16 | lowWord; // receive timestamp seconds

highWord = ( buffer[40] << 8 | buffer[41] ) & 0x0000FFFF;
lowWord = ( buffer[42] << 8 | buffer[43] ) & 0x0000FFFF;
uint32_t secsSince1900 = highWord << 16 | lowWord;
uint32_t secsSince1900 = highWord << 16 | lowWord; // transmit timestamp seconds

highWord = ( buffer[44] << 8 | buffer[45] ) & 0x0000FFFF;
lowWord = ( buffer[46] << 8 | buffer[47] ) & 0x0000FFFF;
uint32_t fraction = highWord << 16 | lowWord; // transmit timestamp fractions

//check if received data makes sense
//buffer[1] = stratum - should be 1..15 for valid reply
//also checking that all timestamps are non-zero and receive timestamp seconds are <= transmit timestamp seconds
if ((buffer[1] < 1) or (buffer[1] > 15) or (reftsSec == 0) or (rcvtsSec == 0) or (rcvtsSec > secsSince1900)) {
// we got invalid packet
triggerError(INVALID_DATA);
return false;
}

// Set the t and measured_at variables that were passed by reference
uint32_t done = millis();
info(F("success (round trip ")); info(done - started); infoln(F(" ms)"));
t = secsSince1900 - 2208988800UL; // Subtract 70 years to get seconds since 1970
highWord = ( buffer[44] << 8 | buffer[45] ) & 0x0000FFFF;
lowWord = ( buffer[46] << 8 | buffer[47] ) & 0x0000FFFF;
uint32_t fraction = highWord << 16 | lowWord; // Must be done via two words on AVR
uint16_t ms = fraction / 4294967UL; // Turn 32 bit fraction into ms by dividing by 2^32 / 1000
measured_at = done - ((done - started) / 2) - ms; // Assume symmetric network latency and return when we think the whole second was.
udp.stop(); // On AVR there's only very limited sockets, we want to free them when done.
return true;
}

Expand Down
5 changes: 3 additions & 2 deletions src/ezTime.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@ typedef enum {
NO_CACHE_SET,
CACHE_TOO_SMALL,
TOO_MANY_EVENTS,
SERVER_ERROR
SERVER_ERROR,
INVALID_DATA
} ezError_t;

typedef enum {
Expand Down Expand Up @@ -344,4 +345,4 @@ namespace ezt {

} // extern "C++"
#endif // __cplusplus
#endif //_EZTIME_H_
#endif //_EZTIME_H_

0 comments on commit de16d0b

Please sign in to comment.