6 #ifndef ACE_TIME_NTP_CLOCK_H
7 #define ACE_TIME_NTP_CLOCK_H
9 #if defined(ESP8266) || defined(ESP32)
13 #include <ESP8266WiFi.h>
18 #include "../common/logging.h"
21 extern "C" unsigned long millis();
23 #ifndef ACE_TIME_NTP_CLOCK_DEBUG
24 #define ACE_TIME_NTP_CLOCK_DEBUG 0
65 mLocalPort(localPort),
66 mRequestTimeout(requestTimeout) {}
78 void setup(
const char* ssid =
nullptr,
const char* password =
nullptr,
79 uint16_t connectTimeoutMillis = kConnectTimeoutMillis) {
81 WiFi.begin(ssid, password);
82 uint16_t startMillis = millis();
83 while (WiFi.status() != WL_CONNECTED) {
84 uint16_t elapsedMillis = millis() - startMillis;
85 if (elapsedMillis >= connectTimeoutMillis) {
94 mUdp.begin(mLocalPort);
96 #if ACE_TIME_NTP_CLOCK_DEBUG == 1
98 SERIAL_PORT_MONITOR.print(F(
"Local port: "));
99 SERIAL_PORT_MONITOR.println(mUdp.localPort());
106 const char* getServer()
const {
return mServer; }
108 bool isSetup()
const {
return mIsSetUp; }
111 if (!mIsSetUp || WiFi.status() != WL_CONNECTED)
return kInvalidSeconds;
115 uint16_t startTime = millis();
116 while ((uint16_t) (millis() - startTime) < mRequestTimeout) {
121 return kInvalidSeconds;
125 if (!mIsSetUp || WiFi.status() != WL_CONNECTED)
return;
128 while (mUdp.parsePacket() > 0) {}
137 IPAddress ntpServerIP;
138 WiFi.hostByName(mServer, ntpServerIP);
139 sendNtpPacket(ntpServerIP);
143 if (!mIsSetUp || WiFi.status() != WL_CONNECTED)
return false;
144 return mUdp.parsePacket() >= kNtpPacketSize;
148 if (!mIsSetUp || WiFi.status() != WL_CONNECTED)
return kInvalidSeconds;
151 mUdp.read(mPacketBuffer, kNtpPacketSize);
154 uint32_t secsSince1900 = (uint32_t) mPacketBuffer[40] << 24;
155 secsSince1900 |= (uint32_t) mPacketBuffer[41] << 16;
156 secsSince1900 |= (uint32_t) mPacketBuffer[42] << 8;
157 secsSince1900 |= (uint32_t) mPacketBuffer[43];
159 return (secsSince1900 == 0)
161 : secsSince1900 - kSecondsSinceNtpEpoch;
166 static const uint8_t kNtpPacketSize = 48;
172 static const uint32_t kSecondsSinceNtpEpoch = 3155673600;
175 static const uint16_t kConnectTimeoutMillis = 10000;
178 void sendNtpPacket(
const IPAddress& address)
const {
179 #if ACE_TIME_NTP_CLOCK_DEBUG == 1
180 uint16_t startTime = millis();
183 memset(mPacketBuffer, 0, kNtpPacketSize);
186 mPacketBuffer[0] = 0b11100011;
187 mPacketBuffer[1] = 0;
188 mPacketBuffer[2] = 6;
189 mPacketBuffer[3] = 0xEC;
191 mPacketBuffer[12] = 49;
192 mPacketBuffer[13] = 0x4E;
193 mPacketBuffer[14] = 49;
194 mPacketBuffer[15] = 52;
197 mUdp.beginPacket(address, 123);
198 mUdp.write(mPacketBuffer, kNtpPacketSize);
200 #if ACE_TIME_NTP_CLOCK_DEBUG == 1
201 logging::printf(
"NtpClock::sendNtpPacket(): %u ms\n",
202 (
unsigned) ((uint16_t) millis() - startTime));
206 const char*
const mServer;
207 uint16_t
const mLocalPort;
208 uint16_t
const mRequestTimeout;
210 mutable WiFiUDP mUdp;
212 mutable uint8_t mPacketBuffer[kNtpPacketSize];
213 bool mIsSetUp =
false;
219 #endif // defined(ESP8266) || defined(ESP32)