|
1 | 1 | /**
|
2 | 2 | * The MIT License (MIT)
|
3 |
| - * Copyright (c) 2015 by Fabrice Weinberg |
| 3 | + * Original work Copyright (c) 2015 by Fabrice Weinberg |
| 4 | + * Modified work Copyright (c) 2020 by Thomas Haggett |
4 | 5 | *
|
5 | 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
|
6 | 7 | * of this software and associated documentation files (the "Software"), to deal
|
@@ -82,48 +83,72 @@ void NTPClient::begin(int port) {
|
82 | 83 | }
|
83 | 84 |
|
84 | 85 | bool NTPClient::forceUpdate() {
|
85 |
| - #ifdef DEBUG_NTPClient |
86 |
| - Serial.println("Update from NTP Server"); |
87 |
| - #endif |
88 |
| - |
89 |
| - // flush any existing packets |
90 |
| - while(this->_udp->parsePacket() != 0) |
91 |
| - this->_udp->flush(); |
| 86 | + this->_lastUpdate = 0; |
| 87 | + this->_requestSent = 0; |
| 88 | + this->_requestDelay = 1; |
| 89 | + return true; |
| 90 | +} |
92 | 91 |
|
93 |
| - this->sendNTPPacket(); |
| 92 | +bool NTPClient::update() { |
| 93 | + int now = millis(); |
94 | 94 |
|
95 |
| - // Wait till data is there or timeout... |
96 |
| - byte timeout = 0; |
97 |
| - int cb = 0; |
98 |
| - do { |
99 |
| - delay ( 10 ); |
100 |
| - cb = this->_udp->parsePacket(); |
101 |
| - if (timeout > 100) return false; // timeout after 1000 ms |
102 |
| - timeout++; |
103 |
| - } while (cb == 0); |
| 95 | + if(!this->_udpSetup) |
| 96 | + this->begin(); |
104 | 97 |
|
105 |
| - this->_lastUpdate = millis() - (10 * (timeout + 1)); // Account for delay in reading the time |
| 98 | + // are we due to send a request? |
| 99 | + if(this->_lastUpdate > 0 && now < this->_lastUpdate + this->_updateInterval) { |
| 100 | + // update isn't due. carry on. |
| 101 | + return false; |
| 102 | + } |
106 | 103 |
|
107 |
| - this->_udp->read(this->_packetBuffer, NTP_PACKET_SIZE); |
| 104 | + // we're due an update - have we sent a request and it has timed out, |
| 105 | + // or not actually sent a request yet? |
| 106 | + if(this->_requestSent == 0 || now > this->_requestSent + this->_requestDelay + REQUEST_TIMEOUT) { |
| 107 | + // if we had already sent a request, let's bump up the _requestDelay so we don't constantly |
| 108 | + // hammer a potentially down NTP server! |
| 109 | + if(this->_requestSent > 0) { |
| 110 | + this->_requestDelay *= 2; |
| 111 | + if(this->_requestDelay > 30000) |
| 112 | + this->_requestDelay = 30000; |
| 113 | + } else { |
| 114 | + // this is the first time we're attempting a send. |
| 115 | + // purge any old packets that might be buffered |
| 116 | + while(this->_udp->parsePacket() != 0) { |
| 117 | + this->_udp->flush(); |
| 118 | + } |
| 119 | + } |
| 120 | + |
| 121 | + // Right. Send an NTP packet! |
| 122 | + // Serial.printf("Sending an NTP packet (timeout=%i)!\n", this->_requestDelay + REQUEST_TIMEOUT); |
| 123 | + this->sendNTPPacket(); |
| 124 | + |
| 125 | + // remember when we last sent a request |
| 126 | + this->_requestSent = now; |
| 127 | + } |
108 | 128 |
|
109 |
| - unsigned long highWord = word(this->_packetBuffer[40], this->_packetBuffer[41]); |
110 |
| - unsigned long lowWord = word(this->_packetBuffer[42], this->_packetBuffer[43]); |
111 |
| - // combine the four bytes (two words) into a long integer |
112 |
| - // this is NTP time (seconds since Jan 1 1900): |
113 |
| - unsigned long secsSince1900 = highWord << 16 | lowWord; |
| 129 | + // check for any replies! |
| 130 | + int length = this->_udp->parsePacket(); |
| 131 | + if( length > 0 ) { |
| 132 | + Serial.println("Got an NTP reply!"); |
| 133 | + this->_udp->read(this->_packetBuffer, NTP_PACKET_SIZE); |
| 134 | + this->_udp->flush(); |
114 | 135 |
|
115 |
| - this->_currentEpoc = secsSince1900 - SEVENZYYEARS; |
| 136 | + unsigned long highWord = word(this->_packetBuffer[40], this->_packetBuffer[41]); |
| 137 | + unsigned long lowWord = word(this->_packetBuffer[42], this->_packetBuffer[43]); |
| 138 | + // combine the four bytes (two words) into a long integer |
| 139 | + // this is NTP time (seconds since Jan 1 1900): |
| 140 | + unsigned long secsSince1900 = highWord << 16 | lowWord; |
116 | 141 |
|
117 |
| - return true; // return true after successful update |
118 |
| -} |
| 142 | + this->_currentEpoc = secsSince1900 - SEVENZYYEARS; |
119 | 143 |
|
120 |
| -bool NTPClient::update() { |
121 |
| - if ((millis() - this->_lastUpdate >= this->_updateInterval) // Update after _updateInterval |
122 |
| - || this->_lastUpdate == 0) { // Update if there was no update yet. |
123 |
| - if (!this->_udpSetup) this->begin(); // setup the UDP client if needed |
124 |
| - return this->forceUpdate(); |
| 144 | + // cleanup and reset our state |
| 145 | + this->_requestSent = 0; |
| 146 | + this->_requestDelay = 1; |
| 147 | + this->_lastUpdate = now; |
| 148 | + return true; |
125 | 149 | }
|
126 |
| - return false; // return false if update does not occur |
| 150 | + |
| 151 | + return false; |
127 | 152 | }
|
128 | 153 |
|
129 | 154 | unsigned long NTPClient::getEpochTime() const {
|
|
0 commit comments